summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Helmle2011-06-13 10:59:23 +0000
committerBernd Helmle2011-06-13 10:59:23 +0000
commitc7be7949ddd9549c2dd359fef2856d407399534e (patch)
tree51db09a0a9d015db94ef9e22b6d69ece0ff920db
parent24979ca58768177d4dac019b69b76d4f83c7ad8f (diff)
parent13000b44d6069743db98ec753763d882b9a0beaf (diff)
Merge branch 'master' of ../bernd_pg into notnull_constraint
-rwxr-xr-xconfigure18
-rw-r--r--configure.in2
-rw-r--r--doc/bug.template2
-rw-r--r--doc/src/sgml/ecpg.sgml31
-rw-r--r--doc/src/sgml/extend.sgml2
-rw-r--r--doc/src/sgml/ref/alter_foreign_table.sgml17
-rw-r--r--doc/src/sgml/release-9.1.sgml374
-rw-r--r--src/backend/access/transam/xlog.c37
-rw-r--r--src/backend/storage/buffer/bufmgr.c10
-rw-r--r--src/backend/storage/file/fd.c93
-rw-r--r--src/backend/storage/lmgr/README-SSI2
-rw-r--r--src/backend/storage/lmgr/predicate.c174
-rw-r--r--src/backend/storage/lmgr/proc.c79
-rw-r--r--src/backend/storage/smgr/md.c9
-rw-r--r--src/backend/storage/smgr/smgr.c17
-rw-r--r--src/backend/utils/adt/pgstatfuncs.c1
-rw-r--r--src/bin/psql/tab-complete.c14
-rw-r--r--src/include/access/xlog_internal.h12
-rw-r--r--src/include/pg_config.h.win328
-rw-r--r--src/include/storage/fd.h1
-rw-r--r--src/include/storage/predicate_internals.h18
-rw-r--r--src/include/storage/smgr.h2
-rw-r--r--src/interfaces/libpq/libpq.rc.in8
-rw-r--r--src/port/win32ver.rc4
-rw-r--r--src/tools/pgindent/README3
-rwxr-xr-xsrc/tools/version_stamp.pl2
26 files changed, 627 insertions, 313 deletions
diff --git a/configure b/configure
index a8c5923118..a2c3aab407 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for PostgreSQL 9.1beta1.
+# Generated by GNU Autoconf 2.63 for PostgreSQL 9.2devel.
#
# Report bugs to <[email protected]>.
#
@@ -598,8 +598,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='PostgreSQL'
PACKAGE_TARNAME='postgresql'
-PACKAGE_VERSION='9.1beta1'
-PACKAGE_STRING='PostgreSQL 9.1beta1'
+PACKAGE_VERSION='9.2devel'
+PACKAGE_STRING='PostgreSQL 9.2devel'
PACKAGE_BUGREPORT='[email protected]'
ac_unique_file="src/backend/access/common/heaptuple.c"
@@ -1415,7 +1415,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures PostgreSQL 9.1beta1 to adapt to many kinds of systems.
+\`configure' configures PostgreSQL 9.2devel to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1480,7 +1480,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of PostgreSQL 9.1beta1:";;
+ short | recursive ) echo "Configuration of PostgreSQL 9.2devel:";;
esac
cat <<\_ACEOF
@@ -1627,7 +1627,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-PostgreSQL configure 9.1beta1
+PostgreSQL configure 9.2devel
generated by GNU Autoconf 2.63
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1643,7 +1643,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by PostgreSQL $as_me 9.1beta1, which was
+It was created by PostgreSQL $as_me 9.2devel, which was
generated by GNU Autoconf 2.63. Invocation command line was
$ $0 $@
@@ -30056,7 +30056,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by PostgreSQL $as_me 9.1beta1, which was
+This file was extended by PostgreSQL $as_me 9.2devel, which was
generated by GNU Autoconf 2.63. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -30123,7 +30123,7 @@ Report bugs to <[email protected]>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-PostgreSQL config.status 9.1beta1
+PostgreSQL config.status 9.2devel
configured by $0, generated by GNU Autoconf 2.63,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.in b/configure.in
index 6a7278aefe..ddc4cc9a16 100644
--- a/configure.in
+++ b/configure.in
@@ -17,7 +17,7 @@ dnl Read the Autoconf manual for details.
dnl
m4_pattern_forbid(^PGAC_)dnl to catch undefined macros
-AC_INIT([PostgreSQL], [9.1beta1], [[email protected]])
+AC_INIT([PostgreSQL], [9.2devel], [[email protected]])
m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.63], [], [m4_fatal([Autoconf version 2.63 is required.
Untested combinations of 'autoconf' and PostgreSQL versions are not
diff --git a/doc/bug.template b/doc/bug.template
index a63853c182..a58716275f 100644
--- a/doc/bug.template
+++ b/doc/bug.template
@@ -27,7 +27,7 @@ System Configuration:
Operating System (example: Linux 2.4.18) :
- PostgreSQL version (example: PostgreSQL 9.1beta1): PostgreSQL 9.1beta1
+ PostgreSQL version (example: PostgreSQL 9.2devel): PostgreSQL 9.2devel
Compiler used (example: gcc 3.3.5) :
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 9130b12d69..def250c156 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -9281,7 +9281,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if an overflow occurred in a
- calculation. Internally it is defined to -1200 (the <productname>Informix</productname>
+ calculation. Internally it is defined as -1200 (the <productname>Informix</productname>
definition).
</para>
</listitem>
@@ -9292,7 +9292,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if an underflow occurred in a calculation.
- Internally it is defined to -1201 (the <productname>Informix</productname> definition).
+ Internally it is defined as -1201 (the <productname>Informix</productname> definition).
</para>
</listitem>
</varlistentry>
@@ -9302,7 +9302,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if an attempt to divide by zero is
- observed. Internally it is defined to -1202 (the <productname>Informix</productname> definition).
+ observed. Internally it is defined as -1202 (the <productname>Informix</productname> definition).
</para>
</listitem>
</varlistentry>
@@ -9312,7 +9312,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if a bad value for a year was found while
- parsing a date. Internally it is defined to -1204 (the <productname>Informix</productname>
+ parsing a date. Internally it is defined as -1204 (the <productname>Informix</productname>
definition).
</para>
</listitem>
@@ -9323,7 +9323,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if a bad value for a month was found while
- parsing a date. Internally it is defined to -1205 (the <productname>Informix</productname>
+ parsing a date. Internally it is defined as -1205 (the <productname>Informix</productname>
definition).
</para>
</listitem>
@@ -9334,7 +9334,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if a bad value for a day was found while
- parsing a date. Internally it is defined to -1206 (the <productname>Informix</productname>
+ parsing a date. Internally it is defined as -1206 (the <productname>Informix</productname>
definition).
</para>
</listitem>
@@ -9346,7 +9346,7 @@ risnull(CINTTYPE, (char *) &i);
<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 to -1209 (the <productname>Informix</productname> definition).
+ Internally it is defined as -1209 (the <productname>Informix</productname> definition).
</para>
</listitem>
</varlistentry>
@@ -9356,7 +9356,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if an error occurred during date
- formatting. Internally it is defined to -1210 (the
+ formatting. Internally it is defined as -1210 (the
<productname>Informix</productname> definition).
</para>
</listitem>
@@ -9367,7 +9367,7 @@ risnull(CINTTYPE, (char *) &i);
<listitem>
<para>
Functions return this value if memory was exhausted during
- their operation. Internally it is defined to -1211 (the
+ their operation. Internally it is defined as -1211 (the
<productname>Informix</productname> definition).
</para>
</listitem>
@@ -9379,7 +9379,7 @@ risnull(CINTTYPE, (char *) &i);
<para>
Functions return this value if a parsing routine was supposed to get a
format mask (like <literal>mmddyy</>) but not all fields were listed
- correctly. Internally it is defined to -1212 (the <productname>Informix</productname> definition).
+ correctly. Internally it is defined as -1212 (the <productname>Informix</productname> definition).
</para>
</listitem>
</varlistentry>
@@ -9392,7 +9392,7 @@ risnull(CINTTYPE, (char *) &i);
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 to -1213 (the <productname>Informix</productname> definition).
+ Internally it is defined as -1213 (the <productname>Informix</productname> definition).
</para>
</listitem>
</varlistentry>
@@ -9401,7 +9401,8 @@ risnull(CINTTYPE, (char *) &i);
<term><literal>ECPG_INFORMIX_BAD_EXPONENT</></term>
<listitem>
<para>
- Functions return this value if Internally it is defined to -1216 (the
+ 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>
@@ -9411,7 +9412,8 @@ risnull(CINTTYPE, (char *) &i);
<term><literal>ECPG_INFORMIX_BAD_DATE</></term>
<listitem>
<para>
- Functions return this value if Internally it is defined to -1218 (the
+ 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>
@@ -9421,7 +9423,8 @@ risnull(CINTTYPE, (char *) &i);
<term><literal>ECPG_INFORMIX_EXTRA_CHARS</></term>
<listitem>
<para>
- Functions return this value if Internally it is defined to -1264 (the
+ Functions return this value if a parsing routine is passed extra
+ characters is cannot parse. Internally it is defined as -1264 (the
<productname>Informix</productname> definition).
</para>
</listitem>
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
index 5ff6d16a41..ab538cb500 100644
--- a/doc/src/sgml/extend.sgml
+++ b/doc/src/sgml/extend.sgml
@@ -354,7 +354,7 @@
considered members of the extension.
</para>
- <sect2 id="extension">
+ <sect2>
<title>Extension Files</title>
<indexterm>
diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml
index c2ebdac847..a45df020ea 100644
--- a/doc/src/sgml/ref/alter_foreign_table.sgml
+++ b/doc/src/sgml/ref/alter_foreign_table.sgml
@@ -32,7 +32,7 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
<phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase>
- ADD [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> <replaceable class="PARAMETER">type</replaceable>
+ ADD [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> <replaceable class="PARAMETER">type</replaceable> [ NULL | NOT NULL ]
DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="PARAMETER">column</replaceable> [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">type</replaceable>
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
@@ -125,7 +125,7 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
<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 the column of the foreign table.
+ Change options for the foreign table.
<literal>ADD</>, <literal>SET</>, and <literal>DROP</>
specify the action to be performed. <literal>ADD</> is assumed
if no operation is explicitly specified. Option names must be
@@ -150,8 +150,6 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
You must own the table to use <command>ALTER FOREIGN TABLE</>.
To change the schema of a foreign table, you must also have
<literal>CREATE</literal> privilege on the new schema.
- To add the table as a new child of a parent table, you must own the
- parent table as well.
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
@@ -260,12 +258,11 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable>
</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 system <literal>oid</> column is added
- or removed, a <literal>CHECK</> or <literal>NOT NULL</> constraint is
- added, or column type is changed with <literal>SET DATA TYPE</>. It is the
- user's responsibility to ensure that the table definition matches the
+ 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</> constraint is
+ added, or a column type is changed with <literal>SET DATA TYPE</>. It is
+ the user's responsibility to ensure that the table definition matches the
remote side.
</para>
diff --git a/doc/src/sgml/release-9.1.sgml b/doc/src/sgml/release-9.1.sgml
index 69f34d36cd..2d6c8edf9b 100644
--- a/doc/src/sgml/release-9.1.sgml
+++ b/doc/src/sgml/release-9.1.sgml
@@ -9,7 +9,7 @@
<simpara>2011-??-??</simpara>
</note>
- <para>CURRENT AS OF 2011-03-15</para>
+ <para>CURRENT AS OF 2011-06-09</para>
<sect2>
<title>Overview</title>
@@ -87,6 +87,9 @@
For example, disallow
<literal><replaceable>composite_value</>.text</literal> and
<literal>text(<replaceable>composite_value</>)</literal>.
+ Unintentional uses of this syntax have frequently resulted in bug
+ reports; although it was not a bug, it seems better to go back to
+ rejecting such expressions.
The <literal>CAST</> and <literal>::</> syntaxes are still available
for use when a cast of an entire composite value is actually intended.
</para>
@@ -106,12 +109,6 @@
rechecking the domain type's constraints, whereas before the checks
were skipped.
</para>
-
- <para>
- Also, such a domain type is no longer allowed to match an
- <type>anyarray</> parameter of a polymorphic function, except by
- explicitly downcasting it to the base array type.
- </para>
</listitem>
</itemizedlist>
@@ -236,7 +233,7 @@
<listitem>
<para>
- Adjust PL/pgSQL's error line reporting code to be consistent
+ Adjust PL/pgSQL's error line numbering code to be consistent
with other PLs (Pavel Stehule)
</para>
@@ -247,6 +244,34 @@
</para>
</listitem>
+ <listitem>
+ <para>
+ Make PL/pgSQL complain about conflicting IN and OUT parameter names
+ (Tom Lane)
+ </para>
+
+ <para>
+ Formerly, the collision was not detected, and the name would just
+ silently refer to only the OUT parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Type modifiers of PL/pgSQL variables are now visible to the SQL parser
+ (Tom Lane)
+ </para>
+
+ <para>
+ A type modifier (such as a varchar length limit) attached to a PL/pgSQL
+ variable was formerly enforced during assignments, but was ignored for
+ all other purposes. Such variables will now behave more like table
+ columns declared with the same modifier. This is not expected to make
+ any visible difference in most cases, but it could result in subtle
+ changes for some SQL commands issued by PL/pgSQL functions.
+ </para>
+ </listitem>
+
</itemizedlist>
</sect3>
@@ -258,7 +283,7 @@
<listitem>
<para>
- Have <link
+ Make <link
linkend="monitoring-stats-funcs-table"><function>pg_stat_reset()</></link>
reset all database-level statistics (Tomas Vondra)
</para>
@@ -303,15 +328,17 @@
<listitem>
<para>
- Allow unlogged tables using the <link
+ Support unlogged tables using the <link
linkend="SQL-CREATETABLE-description"><literal>UNLOGGED</></link>
- clause in <link linkend="SQL-CREATETABLE"><command>CREATE
+ option in <link linkend="SQL-CREATETABLE"><command>CREATE
TABLE</></link> (Robert Haas)
</para>
<para>
- These tables are optimized for performance but are cleared in
- case of a server crash.
+ Such tables provide better update performance than regular tables,
+ but are not crash-safe: their contents are automatically cleared in
+ case of a server crash. Their contents do not propagate to
+ replication slaves, either.
</para>
</listitem>
@@ -369,37 +396,26 @@
<listitem>
<para>
- Allow inheritance table queries to return meaningfully-sorted
- results (Greg Stark, Hans-Jurgen Schonig, Robert Haas, Tom
- Lane)
- </para>
-
- <para>
- This allows optimization of <literal>ORDER BY</> and
- <literal>LIMIT</> clauses in inheritance table queries.
+ Allow inheritance table scans to return meaningfully-sorted
+ results (Greg Stark, Hans-Jurgen Schonig, Robert Haas, Tom Lane)
</para>
- </listitem>
- <listitem>
<para>
- Allow optimizations of <literal>MIN</>/<literal>MAX</> for
- inheritance table queries (Tom Lane)
+ This allows better optimization of queries that use <literal>ORDER
+ BY</>, <literal>LIMIT</>, or <literal>MIN</>/<literal>MAX</> with
+ inherited tables.
</para>
</listitem>
<listitem>
<para>
- Support hashing array values (Tom Lane)
- </para>
-
- <para>
- This provides additional query optimization possibilities.
+ Improve GIN index scan cost estimation (Teodor Sigaev)
</para>
</listitem>
<listitem>
<para>
- Improve GIN index scan cost estimation (Teodor Sigaev)
+ Improve cost estimation for aggregates and window functions (Tom Lane)
</para>
</listitem>
@@ -441,6 +457,20 @@
<listitem>
<para>
+ Reject <literal>local</> lines in <link
+ linkend="auth-pg-hba-conf"><filename>pg_hba.conf</></link>
+ on platforms that don't support Unix-socket connections
+ (Magnus Hagander)
+ </para>
+
+ <para>
+ Formerly, such lines were silently ignored, which could be surprising.
+ This makes the behavior more like other unsupported cases.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Allow <link linkend="gssapi-auth"><acronym>GSSAPI</></link>
to be used to authenticate to servers via <link
linkend="sspi-auth"><acronym>SSPI</></link> (Christian Ullrich)
@@ -452,6 +482,34 @@
</para>
</listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-ident"><literal>ident</literal></link>
+ authentication over local sockets is now known as
+ <link linkend="auth-peer"><literal>peer</literal></link>
+ (Magnus Hagander)
+ </para>
+
+ <para>
+ The old term is still accepted for backward compatibility.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Rewrite <link linkend="auth-peer"><acronym>peer</></link>
+ authentication to avoid use of credential control messages (Tom Lane)
+ </para>
+
+ <para>
+ This change makes the peer authentication code simpler and
+ better-performing. However, it requires the platform to provide the
+ <function>getpeereid</> function or an equivalent socket operation.
+ So far as is known, the only platform for which peer authentication
+ worked before and now will not is pre-5.0 NetBSD.
+ </para>
+ </listitem>
+
</itemizedlist>
</sect4>
@@ -625,7 +683,23 @@
<para>
This avoids the requirement of manually transferring a file
- system backup when creating a standby server.
+ system backup when setting up a standby server.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Add
+ <link linkend="guc-replication-timeout"><varname>replication_timeout</></link>
+ setting (Fujii Masao, Heikki Linnakangas)
+ </para>
+
+ <para>
+ Replication connections that are idle for more than the
+ <varname>replication_timeout</> interval will be terminated
+ automatically. Formerly, a failed connection was typically not
+ detected until the TCP timeout elapsed, which is inconveniently
+ long in many situations.
</para>
</listitem>
@@ -645,23 +719,10 @@
</para>
<para>
- This is a read-only permission used for streaming replication
- and allows non-superusers to initiate replication connections.
+ This is a read-only permission used for streaming replication.
+ It allows a non-superuser role to be used for replication connections.
Previously only superusers could initiate replication
- connections; superusers have this permission by default.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <link linkend="auth-ident"><literal>ident</literal></link>
- authentication over local sockets is now known as
- <link linkend="auth-peer"><literal>peer</literal></link>
- (Magnus Hagander)
- </para>
-
- <para>
- The old term is still accepted for backward compatibility.
+ connections; superusers still have this permission by default.
</para>
</listitem>
@@ -695,7 +756,7 @@
</para>
<para>
- This returns the time on the primary that generated the most
+ This returns the time at which the primary generated the most
recent commit or abort record applied on the standby.
</para>
</listitem>
@@ -822,7 +883,7 @@
<para>
These named restore points can be specified as recovery
targets using the new <filename>recovery.conf</> setting
- <link linkend="recovery-target-name"><varname>recovery_target_name</></link>
+ <link linkend="recovery-target-name"><varname>recovery_target_name</></link>.
</para>
</listitem>
@@ -842,8 +903,8 @@
<para>
Add <link
linkend="guc-restart-after-crash"><varname>restart_after_crash</></link>
- which disables server restart after a backend crash (Robert
- Haas)
+ setting which disables automatic server restart after a backend
+ crash (Robert Haas)
</para>
<para>
@@ -989,6 +1050,23 @@
<listitem>
<para>
+ Add <link linkend="extend-extensions">extensions</link> which
+ simplify packaging of additions to <productname>PostgreSQL</>
+ (Dimitri Fontaine, Tom Lane)
+ </para>
+
+ <para>
+ Extensions are controlled by the new <link
+ linkend="SQL-CREATEEXTENSION"><command>CREATE</></link>/<link
+ linkend="SQL-ALTEREXTENSION"><command>ALTER</></link>/<link
+ linkend="SQL-DROPEXTENSION"><command>DROP EXTENSION</></link>
+ commands. This replaces ad-hoc methods of grouping objects that
+ are added to a <productname>PostgreSQL</> installation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Add support for <link linkend="SQL-CREATEFOREIGNTABLE">foreign
tables</link> (Shigeru Hanada, Robert Haas, Jan Urbanski,
Heikki Linnakangas)
@@ -1043,13 +1121,26 @@
<listitem>
<para>
+ Support <literal>ALTER TABLE <replaceable>name</> {OF | NOT OF}
+ <replaceable>type</></literal>
+ (Noah Misch)
+ </para>
+
+ <para>
+ This syntax allows a standalone table to be made into a typed table,
+ or a typed table to be made standalone.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Add support for more object types in <command>ALTER ... SET
SCHEMA</> commands (Dimitri Fontaine)
</para>
<para>
This command is now supported for conversions, operators, operator
- classes, operator families, text search configurations, and text search
+ classes, operator families, text search configurations, text search
dictionaries, text search parsers, and text search templates.
</para>
</listitem>
@@ -1071,7 +1162,7 @@
</para>
<para>
- This allows a primary key or unique constraint to be added using an
+ This allows a primary key or unique constraint to be defined using an
existing unique index, including a concurrently created unique index.
</para>
</listitem>
@@ -1120,8 +1211,8 @@
<listitem>
<para>
Fix possible <quote>tuple concurrently updated</quote> error
- when two server backends attempted to add an inheritance
- parent to the same table at the same time (Robert Haas)
+ when two backends attempted to add an inheritance
+ child to the same table at the same time (Robert Haas)
</para>
<para>
@@ -1356,7 +1447,7 @@
<listitem>
<para>
Allow <type>numeric</> to use a more compact, two-byte header
- in many cases (Robert Haas)
+ in common cases (Robert Haas)
</para>
<para>
@@ -1388,6 +1479,30 @@
</para>
</listitem>
+ <listitem>
+ <para>
+ Support hashing array values (Tom Lane)
+ </para>
+
+ <para>
+ This provides additional query optimization possibilities.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Don't treat a composite type as sortable unless all its column types
+ are sortable (Tom Lane)
+ </para>
+
+ <para>
+ This avoids possible <quote>could not identify a comparison function</>
+ failures at runtime, if it is possible to implement the query without
+ sorting. Also, <command>ANALYZE</> won't try to use inappropriate
+ statistics-gathering methods for columns of such composite types.
+ </para>
+ </listitem>
+
</itemizedlist>
<sect4>
@@ -1402,6 +1517,13 @@
</para>
</listitem>
+ <listitem>
+ <para>
+ Add support for casting from <type>int4</> and <type>int8</>
+ to <type>numeric</> (Joey Adams)
+ </para>
+ </listitem>
+
<listitem>
<para>
Allow casting a table's row type to the table's supertype if
@@ -1538,9 +1660,12 @@
</para>
<para>
- This function is used to obtain a human-readable string describing an
- object, based on the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> OID, object OID, and sub-object OID. It can be used to
- help interpret the contents of <link linkend="catalog-pg-depend"><structname>pg_depend</structname></link>.
+ This function is used to obtain a human-readable string describing
+ an object, based on the <link
+ linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ OID, object OID, and sub-object ID. It can be used to help
+ interpret the contents of <link
+ linkend="catalog-pg-depend"><structname>pg_depend</structname></link>.
</para>
</listitem>
@@ -1549,6 +1674,11 @@
Update comments for built-in operators and their underlying
functions (Tom Lane)
</para>
+
+ <para>
+ Functions that are meant to be used via an associated operator
+ are now commented as such.
+ </para>
</listitem>
<listitem>
@@ -1603,7 +1733,7 @@
<listitem>
<para>
- Allow <link linkend="SQL-CREATETRIGGER"><literal>INSTEAD
+ Support <link linkend="SQL-CREATETRIGGER"><literal>INSTEAD
OF</></link> triggers on views (Dean Rasheed)
</para>
@@ -1774,6 +1904,12 @@
<listitem>
<para>
+ Add traceback information to PL/Python errors (Jan Urbanski)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Report PL/Python errors from iterators with <literal>PLy_elog</> (Jan
Urbanski)
</para>
@@ -1820,7 +1956,7 @@
<listitem>
<para>
- Add the <literal>\conninfo</> command to <application>psql</>,
+ Add <application>psql</> command <literal>\conninfo</>
to show current connection information (David Christensen)
</para>
</listitem>
@@ -1841,8 +1977,8 @@
<listitem>
<para>
- Add system table <option>S</> option to <application>psql</>
- <literal>\dn</> (schemas) (Tom Lane)
+ Add <option>S</> (<quote>system</>) option to <application>psql</>'s
+ <literal>\dn</> (list schemas) command (Tom Lane)
</para>
<para>
@@ -1859,8 +1995,8 @@
</para>
<para>
- This is passed to the editor using the
- <envar>EDITOR_LINENUMBER_SWITCH</> environment variable.
+ This is passed to the editor according to the
+ <envar>EDITOR_LINENUMBER_SWITCH</> psql variable.
</para>
</listitem>
@@ -1878,13 +2014,26 @@
<listitem>
<para>
- Make <application>psql</application> distinguish between unique
+ Make <literal>\d</literal> distinguish between unique
indexes and unique constraints (Josh Kupershmidt)
</para>
</listitem>
<listitem>
<para>
+ Make <literal>\dt+</literal> report <function>pg_table_size</>
+ instead of <function>pg_relation_size</> when talking to 9.0 or
+ later servers (Bernd Helmle)
+ </para>
+
+ <para>
+ This is a more useful measure of table size, but note that it is
+ not identical to what was previously reported in the same display.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Additional tab completion support (Itagaki Takahiro, Pavel Stehule,
Andrey Popp, Christoph Berg, David Fetter, Josh Kupershmidt)
</para>
@@ -1946,9 +2095,14 @@
<listitem>
<para>
Improve <application>pg_ctl</> start's <quote>wait</quote>
- (<option>-w</>) mode to handle non-standard port numbers,
- non-standard Unix-domain socket locations, permission
- problems, and stale postmaster lock files (Bruce Momjian)
+ (<option>-w</>) option (Bruce Momjian, Tom Lane)
+ </para>
+
+ <para>
+ The wait mode is now significantly more robust. It will not get
+ confused by non-default postmaster port numbers, non-default
+ Unix-domain socket locations, permission problems, or stale
+ postmaster lock files.
</para>
</listitem>
@@ -2002,15 +2156,16 @@
<listitem>
<para>
- Allow libpq database clients to use Unix-domain sockets to
+ Allow libpq database clients to
check the user name of the server process using <link
linkend="libpq-connect-requirepeer"><literal>requirepeer</></link>
+ when connecting via Unix-domain sockets
(Peter Eisentraut)
</para>
<para>
- <productname>PostgreSQL</> already allowed servers to determine
- the client user name via Unix-domain sockets.
+ <productname>PostgreSQL</> already allowed servers to check
+ the client user name when connecting via Unix-domain sockets.
</para>
</listitem>
@@ -2023,8 +2178,8 @@
</para>
<para>
- The allow detection of the server's status without creating
- a new session.
+ These functions allow detection of the server's status without
+ trying to open a new session.
</para>
</listitem>
@@ -2056,18 +2211,13 @@
<listitem>
<para>
- Add <link linkend="extension">extensions</link> which simplify
- packaging of additions to <productname>PostgreSQL</> (Dimitri
- Fontaine, Tom Lane)
+ Use <literal>+Olibmerrno</> compile flag with HP-UX C compilers
+ that accept it (Ibrar Ahmed)
</para>
<para>
- This is controlled by the new <link
- linkend="SQL-CREATEEXTENSION"><command>CREATE</></link>/<link
- linkend="SQL-ALTEREXTENSION"><command>ALTER</></link>/<link
- linkend="SQL-DROPEXTENSION"><command>DROP EXTENSION </></link>
- command; this replaces a more manual method of adding features
- to <productname>PostgreSQL</>.
+ This avoids possible misbehavior of math library calls on recent
+ HP platforms.
</para>
</listitem>
@@ -2085,7 +2235,7 @@
<para>
This allows for faster compiles. Also, <literal>make -k</>
- now works properly.
+ now works more consistently.
</para>
</listitem>
@@ -2101,6 +2251,33 @@
</para>
</listitem>
+ <listitem>
+ <para>
+ Add <literal>make maintainer-check</> target
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ This target performs various source code checks that are not
+ appropriate for either the build or the regression tests. Currently:
+ duplicate_oids, SGML syntax and tabs check, NLS syntax check.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Support <literal>make check</> in <filename>contrib</>
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ Formerly only <literal>make installcheck</> worked, but now
+ there is support for testing in a temporary installation.
+ The top-level <literal>make check-world</> target now includes
+ testing <filename>contrib</> this way.
+ </para>
+ </listitem>
+
</itemizedlist>
</sect4>
@@ -2137,7 +2314,7 @@
<para>
This allows building 64-bit Windows binaries even on non-Windows
- platforms with cross-compiling.
+ platforms via cross-compiling.
</para>
</listitem>
@@ -2154,6 +2331,19 @@
<listitem>
<para>
+ Revise the API for GUC variable assign hooks (Tom Lane)
+ </para>
+
+ <para>
+ The previous functions of assign hooks are now split between check
+ hooks and assign hooks, where the former can fail but the latter
+ shouldn't. This change will impact add-on modules that define custom
+ GUC parameters.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
Add latches to the source code to wait for events (Heikki
Linnakangas)
</para>
@@ -2267,13 +2457,9 @@
<para>
Modify <filename>contrib</> modules and stored procedure
languages to install via the new <link
- linkend="extension">extension</link> mechanism (Tom Lane,
+ linkend="extend-extensions">extension</link> mechanism (Tom Lane,
Dimitri Fontaine)
</para>
-
- <para>
- This replaces a more manual method of installation.
- </para>
</listitem>
<listitem>
@@ -2307,9 +2493,9 @@
<listitem>
<para>
- Allow <link
+ Fix <link
linkend="fuzzystrmatch"><filename>contrib/fuzzystrmatch</></link>'s
- <function>levenshtein()</> function handle multibyte characters
+ <function>levenshtein()</> function to handle multibyte characters
(Alexander Korotkov)
</para>
</listitem>
@@ -2569,7 +2755,7 @@
</para>
<para>
- This parameter shows table storage options.
+ This function shows table storage options in a readable form.
</para>
</listitem>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 5c3ca479fb..aa0b0291ee 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3728,23 +3728,32 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
RecPtr = &tmpRecPtr;
/*
- * Align recptr to next page if no more records can fit on the current
- * page.
+ * RecPtr is pointing to end+1 of the previous WAL record. We must
+ * advance it if necessary to where the next record starts. First,
+ * align to next page if no more records can fit on the current page.
*/
if (XLOG_BLCKSZ - (RecPtr->xrecoff % XLOG_BLCKSZ) < SizeOfXLogRecord)
- {
- NextLogPage(tmpRecPtr);
- /* We will account for page header size below */
- }
+ NextLogPage(*RecPtr);
- if (tmpRecPtr.xrecoff >= XLogFileSize)
+ /* Check for crossing of xlog segment boundary */
+ if (RecPtr->xrecoff >= XLogFileSize)
{
- (tmpRecPtr.xlogid)++;
- tmpRecPtr.xrecoff = 0;
+ (RecPtr->xlogid)++;
+ RecPtr->xrecoff = 0;
}
+
+ /*
+ * If at page start, we must skip over the page header. But we can't
+ * do that until we've read in the page, since the header size is
+ * variable.
+ */
}
else
{
+ /*
+ * In this case, the passed-in record pointer should already be
+ * pointing to a valid record starting position.
+ */
if (!XRecOffIsValid(RecPtr->xrecoff))
ereport(PANIC,
(errmsg("invalid record offset at %X/%X",
@@ -3773,11 +3782,13 @@ retry:
if (targetRecOff == 0)
{
/*
- * Can only get here in the continuing-from-prev-page case, because
- * XRecOffIsValid eliminated the zero-page-offset case otherwise. Need
- * to skip over the new page's header.
+ * At page start, so skip over page header. The Assert checks that
+ * we're not scribbling on caller's record pointer; it's OK because we
+ * can only get here in the continuing-from-prev-record case, since
+ * XRecOffIsValid rejected the zero-page-offset case otherwise.
*/
- tmpRecPtr.xrecoff += pageHeaderSize;
+ Assert(RecPtr == &tmpRecPtr);
+ RecPtr->xrecoff += pageHeaderSize;
targetRecOff = pageHeaderSize;
}
else if (targetRecOff < pageHeaderSize)
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index f96685db50..b12348b39d 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -1834,7 +1834,10 @@ BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum,
* written.)
*
* If the caller has an smgr reference for the buffer's relation, pass it
- * as the second parameter. If not, pass NULL.
+ * as the second parameter. If not, pass NULL. In the latter case, the
+ * relation will be marked as "transient" so that the corresponding
+ * kernel-level file descriptors are closed when the current transaction ends,
+ * if any.
*/
static void
FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
@@ -1856,9 +1859,12 @@ FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
errcontext.previous = error_context_stack;
error_context_stack = &errcontext;
- /* Find smgr relation for buffer */
+ /* Find smgr relation for buffer, and mark it as transient */
if (reln == NULL)
+ {
reln = smgropen(buf->tag.rnode, InvalidBackendId);
+ smgrsettransient(reln);
+ }
TRACE_POSTGRESQL_BUFFER_FLUSH_START(buf->tag.forkNum,
buf->tag.blockNum,
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 11bab38280..820e6dbfd9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -125,12 +125,11 @@ static int max_safe_fds = 32; /* default if not changed */
/* these are the assigned bits in fdstate below: */
#define FD_TEMPORARY (1 << 0) /* T = delete when closed */
#define FD_XACT_TEMPORARY (1 << 1) /* T = delete at eoXact */
+#define FD_XACT_TRANSIENT (1 << 2) /* T = close (not delete) at aoXact,
+ * but keep VFD */
-/*
- * Flag to tell whether it's worth scanning VfdCache looking for temp files to
- * close
- */
-static bool have_xact_temporary_files = false;
+/* Flag to tell whether there are files to close/delete at end of transaction */
+static bool have_pending_fd_cleanup = false;
typedef struct vfd
{
@@ -562,7 +561,7 @@ _dump_lru(void)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d ", mru);
}
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "LEAST");
- elog(LOG, buf);
+ elog(LOG, "%s", buf);
}
#endif /* FDDEBUG */
@@ -591,6 +590,7 @@ LruDelete(File file)
Vfd *vfdP;
Assert(file != 0);
+ Assert(!FileIsNotOpen(file));
DO_DB(elog(LOG, "LruDelete %d (%s)",
file, VfdCache[file].fileName));
@@ -953,7 +953,7 @@ OpenTemporaryFile(bool interXact)
VfdCache[file].resowner = CurrentResourceOwner;
/* ensure cleanup happens at eoxact */
- have_xact_temporary_files = true;
+ have_pending_fd_cleanup = true;
}
return file;
@@ -1027,6 +1027,25 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
}
/*
+ * Set the transient flag on a file
+ *
+ * This flag tells CleanupTempFiles to close the kernel-level file descriptor
+ * (but not the VFD itself) at end of transaction.
+ */
+void
+FileSetTransient(File file)
+{
+ Vfd *vfdP;
+
+ Assert(FileIsValid(file));
+
+ vfdP = &VfdCache[file];
+ vfdP->fdstate |= FD_XACT_TRANSIENT;
+
+ have_pending_fd_cleanup = true;
+}
+
+/*
* close a file when done with it
*/
void
@@ -1778,8 +1797,9 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
* particularly care which). All still-open per-transaction temporary file
* VFDs are closed, which also causes the underlying files to be deleted
* (although they should've been closed already by the ResourceOwner
- * cleanup). Furthermore, all "allocated" stdio files are closed. We also
- * forget any transaction-local temp tablespace list.
+ * cleanup). Transient files have their kernel file descriptors closed.
+ * Furthermore, all "allocated" stdio files are closed. We also forget any
+ * transaction-local temp tablespace list.
*/
void
AtEOXact_Files(void)
@@ -1802,7 +1822,10 @@ AtProcExit_Files(int code, Datum arg)
}
/*
- * Close temporary files and delete their underlying files.
+ * General cleanup routine for fd.c.
+ *
+ * Temporary files are closed, and their underlying files deleted.
+ * Transient files are closed.
*
* isProcExit: if true, this is being called as the backend process is
* exiting. If that's the case, we should remove all temporary files; if
@@ -1819,35 +1842,51 @@ CleanupTempFiles(bool isProcExit)
* Careful here: at proc_exit we need extra cleanup, not just
* xact_temporary files.
*/
- if (isProcExit || have_xact_temporary_files)
+ if (isProcExit || have_pending_fd_cleanup)
{
Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
for (i = 1; i < SizeVfdCache; i++)
{
unsigned short fdstate = VfdCache[i].fdstate;
- if ((fdstate & FD_TEMPORARY) && VfdCache[i].fileName != NULL)
+ if (VfdCache[i].fileName != NULL)
{
- /*
- * If we're in the process of exiting a backend process, close
- * all temporary files. Otherwise, only close temporary files
- * local to the current transaction. They should be closed by
- * the ResourceOwner mechanism already, so this is just a
- * debugging cross-check.
- */
- if (isProcExit)
- FileClose(i);
- else if (fdstate & FD_XACT_TEMPORARY)
+ if (fdstate & FD_TEMPORARY)
+ {
+ /*
+ * If we're in the process of exiting a backend process, close
+ * all temporary files. Otherwise, only close temporary files
+ * local to the current transaction. They should be closed by
+ * the ResourceOwner mechanism already, so this is just a
+ * debugging cross-check.
+ */
+ if (isProcExit)
+ FileClose(i);
+ else if (fdstate & FD_XACT_TEMPORARY)
+ {
+ elog(WARNING,
+ "temporary file %s not closed at end-of-transaction",
+ VfdCache[i].fileName);
+ FileClose(i);
+ }
+ }
+ else if (fdstate & FD_XACT_TRANSIENT)
{
- elog(WARNING,
- "temporary file %s not closed at end-of-transaction",
- VfdCache[i].fileName);
- FileClose(i);
+ /*
+ * Close the FD, and remove the entry from the LRU ring,
+ * but also remove the flag from the VFD. This is to
+ * ensure that if the VFD is reused in the future for
+ * non-transient access, we don't close it inappropriately
+ * then.
+ */
+ if (!FileIsNotOpen(i))
+ LruDelete(i);
+ VfdCache[i].fdstate &= ~FD_XACT_TRANSIENT;
}
}
}
- have_xact_temporary_files = false;
+ have_pending_fd_cleanup = false;
}
/* Clean up "allocated" stdio files and dirs. */
diff --git a/src/backend/storage/lmgr/README-SSI b/src/backend/storage/lmgr/README-SSI
index c079e38b90..c685beef4a 100644
--- a/src/backend/storage/lmgr/README-SSI
+++ b/src/backend/storage/lmgr/README-SSI
@@ -389,7 +389,7 @@ locks.
* Because PostgreSQL does not have the same concept of an "oldest
transaction ID" for all serializable transactions as assumed in the
-Cahill these, we track the oldest snapshot xmin among serializable
+Cahill thesis, we track the oldest snapshot xmin among serializable
transactions, and a count of how many active transactions use that
xmin. When the count hits zero we find the new oldest xmin and run a
clean-up based on that.
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 8b1a3336ca..02f5d033b2 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -392,10 +392,11 @@ static HTAB *LocalPredicateLockHash = NULL;
/*
* Keep a pointer to the currently-running serializable transaction (if any)
- * for quick reference.
- * TODO SSI: Remove volatile qualifier and the then-unnecessary casts?
+ * for quick reference. Also, remember if we have written anything that could
+ * cause a rw-conflict.
*/
-static volatile SERIALIZABLEXACT *MySerializableXact = InvalidSerializableXact;
+static SERIALIZABLEXACT *MySerializableXact = InvalidSerializableXact;
+static bool MyXactDidWrite = false;
/* local functions */
@@ -703,8 +704,8 @@ OldSerXidInit(void)
* Set up SLRU management of the pg_serial data.
*/
OldSerXidSlruCtl->PagePrecedes = OldSerXidPagePrecedesLogically;
- SimpleLruInit(OldSerXidSlruCtl, "OldSerXid SLRU Ctl", NUM_OLDSERXID_BUFFERS, 0,
- OldSerXidLock, "pg_serial");
+ SimpleLruInit(OldSerXidSlruCtl, "OldSerXid SLRU Ctl",
+ NUM_OLDSERXID_BUFFERS, 0, OldSerXidLock, "pg_serial");
/* Override default assumption that writes should be fsync'd */
OldSerXidSlruCtl->do_fsync = false;
@@ -1424,20 +1425,29 @@ GetSafeSnapshot(Snapshot origSnapshot)
if (MySerializableXact == InvalidSerializableXact)
return snapshot; /* no concurrent r/w xacts; it's safe */
- MySerializableXact->flags |= SXACT_FLAG_DEFERRABLE_WAITING;
+ LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
/*
* Wait for concurrent transactions to finish. Stop early if one of
* them marked us as conflicted.
*/
- while (!(SHMQueueEmpty((SHM_QUEUE *)
- &MySerializableXact->possibleUnsafeConflicts) ||
+ MySerializableXact->flags |= SXACT_FLAG_DEFERRABLE_WAITING;
+ while (!(SHMQueueEmpty(&MySerializableXact->possibleUnsafeConflicts) ||
SxactIsROUnsafe(MySerializableXact)))
+ {
+ LWLockRelease(SerializableXactHashLock);
ProcWaitForSignal();
-
+ LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
+ }
MySerializableXact->flags &= ~SXACT_FLAG_DEFERRABLE_WAITING;
+
if (!SxactIsROUnsafe(MySerializableXact))
+ {
+ LWLockRelease(SerializableXactHashLock);
break; /* success */
+ }
+
+ LWLockRelease(SerializableXactHashLock);
/* else, need to retry... */
ereport(DEBUG2,
@@ -1600,6 +1610,7 @@ RegisterSerializableTransactionInt(Snapshot snapshot)
}
MySerializableXact = sxact;
+ MyXactDidWrite = false; /* haven't written anything yet */
LWLockRelease(SerializableXactHashLock);
@@ -1635,24 +1646,24 @@ RegisterPredicateLockingXid(const TransactionId xid)
if (MySerializableXact == InvalidSerializableXact)
return;
- /* This should only be done once per transaction. */
- Assert(MySerializableXact->topXid == InvalidTransactionId);
-
/* We should have a valid XID and be at the top level. */
Assert(TransactionIdIsValid(xid));
+ LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
+
+ /* This should only be done once per transaction. */
+ Assert(MySerializableXact->topXid == InvalidTransactionId);
+
MySerializableXact->topXid = xid;
sxidtag.xid = xid;
- LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
sxid = (SERIALIZABLEXID *) hash_search(SerializableXidHash,
&sxidtag,
HASH_ENTER, &found);
- Assert(sxid != NULL);
Assert(!found);
/* Initialize the structure. */
- sxid->myXact = (SERIALIZABLEXACT *) MySerializableXact;
+ sxid->myXact = MySerializableXact;
LWLockRelease(SerializableXactHashLock);
}
@@ -1881,7 +1892,7 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag)
PREDICATELOCK *predlock;
LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED);
- sxact = (SERIALIZABLEXACT *) MySerializableXact;
+ sxact = MySerializableXact;
predlock = (PREDICATELOCK *)
SHMQueueNext(&(sxact->predicateLocks),
&(sxact->predicateLocks),
@@ -2200,8 +2211,7 @@ PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag)
locallock->childLocks = 0;
/* Actually create the lock */
- CreatePredicateLock(targettag, targettaghash,
- (SERIALIZABLEXACT *) MySerializableXact);
+ CreatePredicateLock(targettag, targettaghash, MySerializableXact);
/*
* Lock has been acquired. Check whether it should be promoted to a
@@ -2954,7 +2964,8 @@ PredicateLockPageCombine(const Relation relation, const BlockNumber oldblkno,
}
/*
- * Walk the hash table and find the new xmin.
+ * Walk the list of in-progress serializable transactions and find the new
+ * xmin.
*/
static void
SetNewSxactGlobalXmin(void)
@@ -3041,7 +3052,7 @@ ReleasePredicateLocks(const bool isCommit)
Assert(IsolationIsSerializable());
/* We'd better not already be on the cleanup list. */
- Assert(!SxactIsOnFinishedList((SERIALIZABLEXACT *) MySerializableXact));
+ Assert(!SxactIsOnFinishedList(MySerializableXact));
topLevelIsDeclaredReadOnly = SxactIsReadOnly(MySerializableXact);
@@ -3069,7 +3080,7 @@ ReleasePredicateLocks(const bool isCommit)
MySerializableXact->flags |= SXACT_FLAG_COMMITTED;
MySerializableXact->commitSeqNo = ++(PredXact->LastSxactCommitSeqNo);
/* Recognize implicit read-only transaction (commit without write). */
- if (!(MySerializableXact->flags & SXACT_FLAG_DID_WRITE))
+ if (!MyXactDidWrite)
MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
}
else
@@ -3102,13 +3113,13 @@ ReleasePredicateLocks(const bool isCommit)
* opposed to 'outLink' for the r/w xacts.
*/
possibleUnsafeConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
- (SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
+ SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
+ &MySerializableXact->possibleUnsafeConflicts,
offsetof(RWConflictData, inLink));
while (possibleUnsafeConflict)
{
nextConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
+ SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
&possibleUnsafeConflict->inLink,
offsetof(RWConflictData, inLink));
@@ -3126,6 +3137,10 @@ ReleasePredicateLocks(const bool isCommit)
&& !SxactIsReadOnly(MySerializableXact)
&& SxactHasSummaryConflictOut(MySerializableXact))
{
+ /*
+ * we don't know which old committed transaction we conflicted with,
+ * so be conservative and use FirstNormalSerCommitSeqNo here
+ */
MySerializableXact->SeqNo.earliestOutConflictCommit =
FirstNormalSerCommitSeqNo;
MySerializableXact->flags |= SXACT_FLAG_CONFLICT_OUT;
@@ -3137,13 +3152,13 @@ ReleasePredicateLocks(const bool isCommit)
* previously committed transactions.
*/
conflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->outConflicts,
- (SHM_QUEUE *) &MySerializableXact->outConflicts,
+ SHMQueueNext(&MySerializableXact->outConflicts,
+ &MySerializableXact->outConflicts,
offsetof(RWConflictData, outLink));
while (conflict)
{
nextConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->outConflicts,
+ SHMQueueNext(&MySerializableXact->outConflicts,
&conflict->outLink,
offsetof(RWConflictData, outLink));
@@ -3170,13 +3185,13 @@ ReleasePredicateLocks(const bool isCommit)
* we're rolling back, clear them all.
*/
conflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->inConflicts,
- (SHM_QUEUE *) &MySerializableXact->inConflicts,
+ SHMQueueNext(&MySerializableXact->inConflicts,
+ &MySerializableXact->inConflicts,
offsetof(RWConflictData, inLink));
while (conflict)
{
nextConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->inConflicts,
+ SHMQueueNext(&MySerializableXact->inConflicts,
&conflict->inLink,
offsetof(RWConflictData, inLink));
@@ -3197,13 +3212,13 @@ ReleasePredicateLocks(const bool isCommit)
* up if they are known safe or known unsafe.
*/
possibleUnsafeConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
- (SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
+ SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
+ &MySerializableXact->possibleUnsafeConflicts,
offsetof(RWConflictData, outLink));
while (possibleUnsafeConflict)
{
nextConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->possibleUnsafeConflicts,
+ SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
&possibleUnsafeConflict->outLink,
offsetof(RWConflictData, outLink));
@@ -3213,7 +3228,7 @@ ReleasePredicateLocks(const bool isCommit)
/* Mark conflicted if necessary. */
if (isCommit
- && (MySerializableXact->flags & SXACT_FLAG_DID_WRITE)
+ && MyXactDidWrite
&& SxactHasConflictOut(MySerializableXact)
&& (MySerializableXact->SeqNo.earliestOutConflictCommit
<= roXact->SeqNo.lastCommitBeforeSnapshot))
@@ -3274,11 +3289,10 @@ ReleasePredicateLocks(const bool isCommit)
/* Add this to the list of transactions to check for later cleanup. */
if (isCommit)
SHMQueueInsertBefore(FinishedSerializableTransactions,
- (SHM_QUEUE *) &(MySerializableXact->finishedLink));
+ &MySerializableXact->finishedLink);
if (!isCommit)
- ReleaseOneSerializableXact((SERIALIZABLEXACT *) MySerializableXact,
- false, false);
+ ReleaseOneSerializableXact(MySerializableXact, false, false);
LWLockRelease(SerializableFinishedListLock);
@@ -3286,6 +3300,7 @@ ReleasePredicateLocks(const bool isCommit)
ClearOldPredicateLocks();
MySerializableXact = InvalidSerializableXact;
+ MyXactDidWrite = false;
/* Delete per-transaction lock table */
if (LocalPredicateLockHash != NULL)
@@ -3320,7 +3335,8 @@ ReleasePredicateLocksIfROSafe(void)
}
/*
- * Clear old predicate locks.
+ * Clear old predicate locks, belonging to committed transactions that are no
+ * longer interesting to any in-progress transaction.
*/
static void
ClearOldPredicateLocks(void)
@@ -3328,6 +3344,10 @@ ClearOldPredicateLocks(void)
SERIALIZABLEXACT *finishedSxact;
PREDICATELOCK *predlock;
+ /*
+ * Loop through finished transactions. They are in commit order, so we can
+ * stop as soon as we find one that's still interesting.
+ */
LWLockAcquire(SerializableFinishedListLock, LW_EXCLUSIVE);
finishedSxact = (SERIALIZABLEXACT *)
SHMQueueNext(FinishedSerializableTransactions,
@@ -3346,6 +3366,10 @@ ClearOldPredicateLocks(void)
|| TransactionIdPrecedesOrEquals(finishedSxact->finishedBefore,
PredXact->SxactGlobalXmin))
{
+ /*
+ * This transaction committed before any in-progress transaction
+ * took its snapshot. It's no longer interesting.
+ */
LWLockRelease(SerializableXactHashLock);
SHMQueueDelete(&(finishedSxact->finishedLink));
ReleaseOneSerializableXact(finishedSxact, false, false);
@@ -3362,7 +3386,10 @@ ClearOldPredicateLocks(void)
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
}
else
+ {
+ /* Still interesting. */
break;
+ }
finishedSxact = nextSxact;
}
LWLockRelease(SerializableXactHashLock);
@@ -3391,17 +3418,19 @@ ClearOldPredicateLocks(void)
canDoPartialCleanup = (predlock->commitSeqNo <= PredXact->CanPartialClearThrough);
LWLockRelease(SerializableXactHashLock);
+ /*
+ * If this lock originally belonged to an old enough transaction, we
+ * can release it.
+ */
if (canDoPartialCleanup)
{
PREDICATELOCKTAG tag;
- SHM_QUEUE *targetLink;
PREDICATELOCKTARGET *target;
PREDICATELOCKTARGETTAG targettag;
uint32 targettaghash;
LWLockId partitionLock;
tag = predlock->tag;
- targetLink = &(predlock->targetLink);
target = tag.myTarget;
targettag = target->tag;
targettaghash = PredicateLockTargetTagHashCode(&targettag);
@@ -3409,7 +3438,7 @@ ClearOldPredicateLocks(void)
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
- SHMQueueDelete(targetLink);
+ SHMQueueDelete(&(predlock->targetLink));
SHMQueueDelete(&(predlock->xactLink));
hash_search_with_hash_value(PredicateLockHash, &tag,
@@ -3437,9 +3466,9 @@ ClearOldPredicateLocks(void)
* delete the transaction.
*
* When the partial flag is set, we can release all predicate locks and
- * out-conflict information -- we've established that there are no longer
+ * in-conflict information -- we've established that there are no longer
* any overlapping read write transactions for which this transaction could
- * matter.
+ * matter -- but keep the transaction entry itself and any outConflicts.
*
* When the summarize flag is set, we've run short of room for sxact data
* and must summarize to the SLRU. Predicate locks are transferred to a
@@ -3460,6 +3489,10 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
Assert(LWLockHeldByMe(SerializableFinishedListLock));
+ /*
+ * First release all the predicate locks held by this xact (or transfer
+ * them to OldCommittedSxact if summarize is true)
+ */
LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED);
predlock = (PREDICATELOCK *)
SHMQueueNext(&(sxact->predicateLocks),
@@ -3545,9 +3578,9 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
sxidtag.xid = sxact->topXid;
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
+ /* Release all outConflicts (unless 'partial' is true) */
if (!partial)
{
- /* Release all outConflicts. */
conflict = (RWConflict)
SHMQueueNext(&sxact->outConflicts,
&sxact->outConflicts,
@@ -3582,9 +3615,9 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
conflict = nextConflict;
}
+ /* Finally, get rid of the xid and the record of the transaction itself. */
if (!partial)
{
- /* Get rid of the xid and the record of the transaction itself. */
if (sxidtag.xid != InvalidTransactionId)
hash_search(SerializableXidHash, &sxidtag, HASH_REMOVE, NULL);
ReleasePredXact(sxact);
@@ -3755,7 +3788,7 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
errhint("The transaction might succeed if retried.")));
if (SxactHasSummaryConflictIn(MySerializableXact)
- || !SHMQueueEmpty((SHM_QUEUE *) &MySerializableXact->inConflicts))
+ || !SHMQueueEmpty(&MySerializableXact->inConflicts))
ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to read/write dependencies among transactions"),
@@ -3828,7 +3861,7 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
return;
}
- if (RWConflictExists((SERIALIZABLEXACT *) MySerializableXact, sxact))
+ if (RWConflictExists(MySerializableXact, sxact))
{
/* We don't want duplicate conflict records in the list. */
LWLockRelease(SerializableXactHashLock);
@@ -3839,12 +3872,13 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
* Flag the conflict. But first, if this conflict creates a dangerous
* structure, ereport an error.
*/
- FlagRWConflict((SERIALIZABLEXACT *) MySerializableXact, sxact);
+ FlagRWConflict(MySerializableXact, sxact);
LWLockRelease(SerializableXactHashLock);
}
/*
- * Check a particular target for rw-dependency conflict in.
+ * Check a particular target for rw-dependency conflict in. A subroutine of
+ * CheckForSerializableConflictIn().
*/
static void
CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
@@ -3920,7 +3954,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
&& (!SxactIsCommitted(sxact)
|| TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
sxact->finishedBefore))
- && !RWConflictExists(sxact, (SERIALIZABLEXACT *) MySerializableXact))
+ && !RWConflictExists(sxact, MySerializableXact))
{
LWLockRelease(SerializableXactHashLock);
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
@@ -3933,10 +3967,9 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
&& (!SxactIsCommitted(sxact)
|| TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
sxact->finishedBefore))
- && !RWConflictExists(sxact,
- (SERIALIZABLEXACT *) MySerializableXact))
+ && !RWConflictExists(sxact, MySerializableXact))
{
- FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact);
+ FlagRWConflict(sxact, MySerializableXact);
}
LWLockRelease(SerializableXactHashLock);
@@ -4041,7 +4074,11 @@ CheckForSerializableConflictIn(const Relation relation, const HeapTuple tuple,
errdetail("Cancelled on identification as a pivot, during conflict in checking."),
errhint("The transaction might succeed if retried.")));
- MySerializableXact->flags |= SXACT_FLAG_DID_WRITE;
+ /*
+ * We're doing a write which might cause rw-conflicts now or later.
+ * Memorize that fact.
+ */
+ MyXactDidWrite = true;
/*
* It is important that we check for locks from the finest granularity to
@@ -4126,6 +4163,12 @@ CheckTableForSerializableConflictIn(const Relation relation)
if (SkipSerialization(relation))
return;
+ /*
+ * We're doing a write which might cause rw-conflicts now or later.
+ * Memorize that fact.
+ */
+ MyXactDidWrite = true;
+
Assert(relation->rd_index == NULL); /* not an index relation */
dbId = relation->rd_node.dbNode;
@@ -4168,10 +4211,10 @@ CheckTableForSerializableConflictIn(const Relation relation)
offsetof(PREDICATELOCK, targetLink));
if (predlock->tag.myXact != MySerializableXact
- && !RWConflictExists(predlock->tag.myXact,
- (SERIALIZABLEXACT *) MySerializableXact))
- FlagRWConflict(predlock->tag.myXact,
- (SERIALIZABLEXACT *) MySerializableXact);
+ && !RWConflictExists(predlock->tag.myXact, MySerializableXact))
+ {
+ FlagRWConflict(predlock->tag.myXact, MySerializableXact);
+ }
predlock = nextpredlock;
}
@@ -4418,8 +4461,8 @@ PreCommit_CheckForSerializationFailure(void)
}
nearConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->inConflicts,
- (SHM_QUEUE *) &MySerializableXact->inConflicts,
+ SHMQueueNext(&MySerializableXact->inConflicts,
+ &MySerializableXact->inConflicts,
offsetof(RWConflictData, inLink));
while (nearConflict)
{
@@ -4452,7 +4495,7 @@ PreCommit_CheckForSerializationFailure(void)
}
nearConflict = (RWConflict)
- SHMQueueNext((SHM_QUEUE *) &MySerializableXact->inConflicts,
+ SHMQueueNext(&MySerializableXact->inConflicts,
&nearConflict->inLink,
offsetof(RWConflictData, inLink));
}
@@ -4482,7 +4525,7 @@ AtPrepare_PredicateLocks(void)
TwoPhasePredicateXactRecord *xactRecord;
TwoPhasePredicateLockRecord *lockRecord;
- sxact = (SERIALIZABLEXACT *) MySerializableXact;
+ sxact = MySerializableXact;
xactRecord = &(record.data.xactRecord);
lockRecord = &(record.data.lockRecord);
@@ -4499,9 +4542,9 @@ AtPrepare_PredicateLocks(void)
* outConflicts lists, if they're non-empty we'll represent that by
* setting the appropriate summary conflict flags.
*/
- if (!SHMQueueEmpty((SHM_QUEUE *) &MySerializableXact->inConflicts))
+ if (!SHMQueueEmpty(&MySerializableXact->inConflicts))
xactRecord->flags |= SXACT_FLAG_SUMMARY_CONFLICT_IN;
- if (!SHMQueueEmpty((SHM_QUEUE *) &MySerializableXact->outConflicts))
+ if (!SHMQueueEmpty(&MySerializableXact->outConflicts))
xactRecord->flags |= SXACT_FLAG_SUMMARY_CONFLICT_OUT;
RegisterTwoPhaseRecord(TWOPHASE_RM_PREDICATELOCK_ID, 0,
@@ -4559,6 +4602,7 @@ PostPrepare_PredicateLocks(TransactionId xid)
LocalPredicateLockHash = NULL;
MySerializableXact = InvalidSerializableXact;
+ MyXactDidWrite = false;
}
/*
@@ -4585,6 +4629,8 @@ PredicateLockTwoPhaseFinish(TransactionId xid, bool isCommit)
/* Release its locks */
MySerializableXact = sxid->myXact;
+ MyXactDidWrite = true; /* conservatively assume that we wrote
+ * something */
ReleasePredicateLocks(isCommit);
}
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index ee03316050..c7b1e45bb8 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -160,6 +160,7 @@ InitProcGlobal(void)
PGPROC *procs;
int i;
bool found;
+ uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS;
/* Create the ProcGlobal shared structure */
ProcGlobal = (PROC_HDR *)
@@ -167,68 +168,60 @@ InitProcGlobal(void)
Assert(!found);
/*
- * Create the PGPROC structures for auxiliary (bgwriter) processes, too.
- * These do not get linked into the freeProcs list.
- */
- AuxiliaryProcs = (PGPROC *)
- ShmemInitStruct("AuxiliaryProcs", NUM_AUXILIARY_PROCS * sizeof(PGPROC),
- &found);
- Assert(!found);
-
- /*
* Initialize the data structures.
*/
+ ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
ProcGlobal->freeProcs = NULL;
ProcGlobal->autovacFreeProcs = NULL;
- ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
-
- /*
- * Pre-create the PGPROC structures and create a semaphore for each.
- */
- procs = (PGPROC *) ShmemAlloc((MaxConnections) * sizeof(PGPROC));
- if (!procs)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of shared memory")));
- MemSet(procs, 0, MaxConnections * sizeof(PGPROC));
- for (i = 0; i < MaxConnections; i++)
- {
- PGSemaphoreCreate(&(procs[i].sem));
- procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
- ProcGlobal->freeProcs = &procs[i];
- InitSharedLatch(&procs[i].waitLatch);
- }
-
/*
- * Likewise for the PGPROCs reserved for autovacuum.
+ * Create and initialize all the PGPROC structures we'll need (except for
+ * those used for 2PC, which are embedded within a GlobalTransactionData
+ * struct).
*
- * Note: the "+1" here accounts for the autovac launcher
+ * There are three separate consumers of PGPROC structures: (1) normal
+ * backends, (2) autovacuum workers and the autovacuum launcher, and (3)
+ * auxiliary processes. Each PGPROC structure is dedicated to exactly
+ * one of these purposes, and they do not move between groups.
*/
- procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers + 1) * sizeof(PGPROC));
+ procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
if (!procs)
ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
- MemSet(procs, 0, (autovacuum_max_workers + 1) * sizeof(PGPROC));
- for (i = 0; i < autovacuum_max_workers + 1; i++)
+ MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
+ for (i = 0; i < TotalProcs; i++)
{
+ /* Common initialization for all PGPROCs, regardless of type. */
PGSemaphoreCreate(&(procs[i].sem));
- procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
- ProcGlobal->autovacFreeProcs = &procs[i];
InitSharedLatch(&procs[i].waitLatch);
+
+ /*
+ * Newly created PGPROCs for normal backends or for autovacuum must
+ * be queued up on the appropriate free list. Because there can only
+ * ever be a small, fixed number of auxiliary processes, no free
+ * list is used in that case; InitAuxiliaryProcess() instead uses a
+ * linear search.
+ */
+ if (i < MaxConnections)
+ {
+ /* PGPROC for normal backend, add to freeProcs list */
+ procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
+ ProcGlobal->freeProcs = &procs[i];
+ }
+ else if (i < MaxBackends)
+ {
+ /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
+ procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
+ ProcGlobal->autovacFreeProcs = &procs[i];
+ }
}
/*
- * And auxiliary procs.
+ * Save a pointer to the block of PGPROC structures reserved for
+ * auxiliary proceses.
*/
- MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
- for (i = 0; i < NUM_AUXILIARY_PROCS; i++)
- {
- AuxiliaryProcs[i].pid = 0; /* marks auxiliary proc as not in use */
- PGSemaphoreCreate(&(AuxiliaryProcs[i].sem));
- InitSharedLatch(&procs[i].waitLatch);
- }
+ AuxiliaryProcs = &procs[MaxBackends];
/* Create ProcStructLock spinlock, too */
ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 5034a1dc4d..7f44606c1a 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -288,6 +288,9 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
pfree(path);
+ if (reln->smgr_transient)
+ FileSetTransient(fd);
+
reln->md_fd[forkNum] = _fdvec_alloc();
reln->md_fd[forkNum]->mdfd_vfd = fd;
@@ -542,6 +545,9 @@ mdopen(SMgrRelation reln, ForkNumber forknum, ExtensionBehavior behavior)
pfree(path);
+ if (reln->smgr_transient)
+ FileSetTransient(fd);
+
reln->md_fd[forknum] = mdfd = _fdvec_alloc();
mdfd->mdfd_vfd = fd;
@@ -1556,6 +1562,9 @@ _mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno,
if (fd < 0)
return NULL;
+ if (reln->smgr_transient)
+ FileSetTransient(fd);
+
/* allocate an mdfdvec entry for it */
v = _fdvec_alloc();
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index a6610bf4f8..be89ee6d91 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -165,17 +165,34 @@ smgropen(RelFileNode rnode, BackendId backend)
reln->smgr_targblock = InvalidBlockNumber;
reln->smgr_fsm_nblocks = InvalidBlockNumber;
reln->smgr_vm_nblocks = InvalidBlockNumber;
+ reln->smgr_transient = false;
reln->smgr_which = 0; /* we only have md.c at present */
/* mark it not open */
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
reln->md_fd[forknum] = NULL;
}
+ else
+ /* if it was transient before, it no longer is */
+ reln->smgr_transient = false;
return reln;
}
/*
+ * smgrsettransient() -- mark an SMgrRelation object as transaction-bound
+ *
+ * The main effect of this is that all opened files are marked to be
+ * kernel-level closed (but not necessarily VFD-closed) when the current
+ * transaction ends.
+ */
+void
+smgrsettransient(SMgrRelation reln)
+{
+ reln->smgr_transient = true;
+}
+
+/*
* smgrsetowner() -- Establish a long-lived reference to an SMgrRelation object
*
* There can be only one owner at a time; this is sufficient since currently
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index f811245cea..12dbff4c9a 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -509,6 +509,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
tupdesc = CreateTemplateTupleDesc(12, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid",
OIDOID, -1, 0);
+ /* This should have been called 'pid'; can't change it. 2011-06-11 */
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid",
INT4OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid",
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 9a7eca0766..a43d6e3159 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1553,9 +1553,10 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "ON") == 0)
{
static const char *const list_COMMENT[] =
- {"CAST", "COLLATION", "CONVERSION", "DATABASE", "FOREIGN DATA WRAPPER",
- "SERVER", "FOREIGN TABLE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
- "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
+ {"CAST", "COLLATION", "CONVERSION", "DATABASE", "EXTENSION",
+ "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
+ "SERVER", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE",
+ "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
"OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
"TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
@@ -1582,11 +1583,10 @@ psql_completion(char *text, int start, int end)
}
else if ((pg_strcasecmp(prev4_wd, "COMMENT") == 0 &&
pg_strcasecmp(prev3_wd, "ON") == 0) ||
+ (pg_strcasecmp(prev5_wd, "COMMENT") == 0 &&
+ pg_strcasecmp(prev4_wd, "ON") == 0) ||
(pg_strcasecmp(prev6_wd, "COMMENT") == 0 &&
- pg_strcasecmp(prev5_wd, "ON") == 0) ||
- (pg_strcasecmp(prev5_wd, "ON") == 0 &&
- pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
- pg_strcasecmp(prev3_wd, "SEARCH") == 0))
+ pg_strcasecmp(prev5_wd, "ON") == 0))
COMPLETE_WITH_CONST("IS");
/* COPY */
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index eeccdce31d..7e39630c1b 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -154,13 +154,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
/* Align a record pointer to next page */
#define NextLogPage(recptr) \
do { \
- if (recptr.xrecoff % XLOG_BLCKSZ != 0) \
- recptr.xrecoff += \
- (XLOG_BLCKSZ - recptr.xrecoff % XLOG_BLCKSZ); \
- if (recptr.xrecoff >= XLogFileSize) \
+ if ((recptr).xrecoff % XLOG_BLCKSZ != 0) \
+ (recptr).xrecoff += \
+ (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ); \
+ if ((recptr).xrecoff >= XLogFileSize) \
{ \
- (recptr.xlogid)++; \
- recptr.xrecoff = 0; \
+ ((recptr).xlogid)++; \
+ (recptr).xrecoff = 0; \
} \
} while (0)
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 54bbb5ae72..e9a04f66db 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -569,16 +569,16 @@
#define PACKAGE_NAME "PostgreSQL"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PostgreSQL 9.1beta1"
+#define PACKAGE_STRING "PostgreSQL 9.2devel"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "9.1beta1"
+#define PACKAGE_VERSION "9.2devel"
/* PostgreSQL version as a string */
-#define PG_VERSION "9.1beta1"
+#define PG_VERSION "9.2devel"
/* PostgreSQL version as a number */
-#define PG_VERSION_NUM 90100
+#define PG_VERSION_NUM 90200
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "postgresql"
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index dc0aada35b..8a4d07c553 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -61,6 +61,7 @@ extern int max_files_per_process;
/* Operations on virtual Files --- equivalent to Unix kernel file ops */
extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
extern File OpenTemporaryFile(bool interXact);
+extern void FileSetTransient(File file);
extern void FileClose(File file);
extern int FilePrefetch(File file, off_t offset, int amount);
extern int FileRead(File file, char *buffer, int amount);
diff --git a/src/include/storage/predicate_internals.h b/src/include/storage/predicate_internals.h
index 56a01f0b91..da6e641f4e 100644
--- a/src/include/storage/predicate_internals.h
+++ b/src/include/storage/predicate_internals.h
@@ -99,14 +99,13 @@ typedef struct SERIALIZABLEXACT
*/
#define SXACT_FLAG_CONFLICT_OUT 0x00000004
#define SXACT_FLAG_READ_ONLY 0x00000008
-#define SXACT_FLAG_DID_WRITE 0x00000010
-#define SXACT_FLAG_MARKED_FOR_DEATH 0x00000020
-#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000040
-#define SXACT_FLAG_RO_SAFE 0x00000080
-#define SXACT_FLAG_RO_UNSAFE 0x00000100
-#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200
-#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400
-#define SXACT_FLAG_PREPARED 0x00000800
+#define SXACT_FLAG_MARKED_FOR_DEATH 0x00000010
+#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000020
+#define SXACT_FLAG_RO_SAFE 0x00000040
+#define SXACT_FLAG_RO_UNSAFE 0x00000080
+#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000100
+#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000200
+#define SXACT_FLAG_PREPARED 0x00000400
/*
* The following types are used to provide an ad hoc list for holding
@@ -134,7 +133,8 @@ typedef struct PredXactListData
/*
* These global variables are maintained when registering and cleaning up
* serializable transactions. They must be global across all backends,
- * but are not needed outside the predicate.c source file.
+ * but are not needed outside the predicate.c source file. Protected
+ * by SerializableXactHashLock.
*/
TransactionId SxactGlobalXmin; /* global xmin for active serializable
* transactions */
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 13f7239c7e..e4792668c2 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -62,6 +62,7 @@ typedef struct SMgrRelationData
* submodules. Do not touch them from elsewhere.
*/
int smgr_which; /* storage manager selector */
+ bool smgr_transient; /* T if files are to be closed at EOXact */
/* for md.c; NULL for forks that are not open */
struct _MdfdVec *md_fd[MAX_FORKNUM + 1];
@@ -74,6 +75,7 @@ typedef SMgrRelationData *SMgrRelation;
extern void smgrinit(void);
extern SMgrRelation smgropen(RelFileNode rnode, BackendId backend);
+extern void smgrsettransient(SMgrRelation reln);
extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
extern void smgrclose(SMgrRelation reln);
diff --git a/src/interfaces/libpq/libpq.rc.in b/src/interfaces/libpq/libpq.rc.in
index adf00b1a28..c9ec034981 100644
--- a/src/interfaces/libpq/libpq.rc.in
+++ b/src/interfaces/libpq/libpq.rc.in
@@ -1,8 +1,8 @@
#include <winver.h>
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 9,1,0,0
- PRODUCTVERSION 9,1,0,0
+ FILEVERSION 9,2,0,0
+ PRODUCTVERSION 9,2,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0
FILEOS VOS__WINDOWS32
@@ -15,13 +15,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "PostgreSQL Access Library\0"
- VALUE "FileVersion", "9.1.0\0"
+ VALUE "FileVersion", "9.2.0\0"
VALUE "InternalName", "libpq\0"
VALUE "LegalCopyright", "Copyright (C) 2011\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libpq.dll\0"
VALUE "ProductName", "PostgreSQL\0"
- VALUE "ProductVersion", "9.1.0\0"
+ VALUE "ProductVersion", "9.2.0\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/port/win32ver.rc b/src/port/win32ver.rc
index a6fddc38bc..46026b3abe 100644
--- a/src/port/win32ver.rc
+++ b/src/port/win32ver.rc
@@ -2,8 +2,8 @@
#include "pg_config.h"
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 9,1,0,0
- PRODUCTVERSION 9,1,0,0
+ FILEVERSION 9,2,0,0
+ PRODUCTVERSION 9,2,0,0
FILEFLAGSMASK 0x17L
FILEFLAGS 0x0L
FILEOS VOS_NT_WINDOWS32
diff --git a/src/tools/pgindent/README b/src/tools/pgindent/README
index 44050c01b3..e81e85d15b 100644
--- a/src/tools/pgindent/README
+++ b/src/tools/pgindent/README
@@ -28,6 +28,9 @@ This can format all PostgreSQL *.c and *.h files, but excludes *.y, and
6) Do a full test build:
run configure
+ # stop is only necessary if it's going to install in a location with an
+ # already running server
+ pg_ctl stop
gmake -C src install
gmake -C contrib install
gmake installcheck-world
diff --git a/src/tools/version_stamp.pl b/src/tools/version_stamp.pl
index ef945da2dd..f6b5325b68 100755
--- a/src/tools/version_stamp.pl
+++ b/src/tools/version_stamp.pl
@@ -23,7 +23,7 @@
# Major version is hard-wired into the script. We update it when we branch
# a new development version.
$major1 = 9;
-$major2 = 1;
+$major2 = 2;
# Validate argument and compute derived variables
$minor = shift;