summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Helmle2011-06-09 15:01:11 +0000
committerBernd Helmle2011-06-09 15:01:11 +0000
commit4f01eeaad0c058a9717ced354cacccce4c52f488 (patch)
tree6f5309ced89ed722ea28b6b90a3a93d8da063d4e
parent5fd3024a3d606946063ffa2ffce0e9167e3f3ec4 (diff)
parent5234161ac10350e009874e4872935a6133d8f0fc (diff)
Merge branch 'master' of ../bernd_pg into notnull_constraint
-rw-r--r--contrib/citext/citext.c23
-rw-r--r--doc/src/sgml/citext.sgml50
-rw-r--r--doc/src/sgml/information_schema.sgml16
-rw-r--r--doc/src/sgml/ref/pg_ctl-ref.sgml42
-rw-r--r--src/backend/parser/parse_coerce.c87
-rw-r--r--src/backend/storage/lmgr/predicate.c3
-rw-r--r--src/bin/pg_ctl/pg_ctl.c90
-rw-r--r--src/test/regress/expected/domain.out36
-rw-r--r--src/test/regress/sql/domain.sql7
9 files changed, 245 insertions, 109 deletions
diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c
index 25e4dd3999..31b952b3f7 100644
--- a/contrib/citext/citext.c
+++ b/contrib/citext/citext.c
@@ -4,6 +4,7 @@
#include "postgres.h"
#include "access/hash.h"
+#include "catalog/pg_collation.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "utils/formatting.h"
@@ -48,8 +49,16 @@ citextcmp(text *left, text *right, Oid collid)
*rcstr;
int32 result;
- lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), collid);
- rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), collid);
+ /*
+ * We must do our str_tolower calls with DEFAULT_COLLATION_OID, not the
+ * input collation as you might expect. This is so that the behavior of
+ * citext's equality and hashing functions is not collation-dependent. We
+ * should change this once the core infrastructure is able to cope with
+ * collation-dependent equality and hashing functions.
+ */
+
+ lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
+ rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
result = varstr_cmp(lcstr, strlen(lcstr),
rcstr, strlen(rcstr),
@@ -93,7 +102,7 @@ citext_hash(PG_FUNCTION_ARGS)
char *str;
Datum result;
- str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), PG_GET_COLLATION());
+ str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID);
result = hash_any((unsigned char *) str, strlen(str));
pfree(str);
@@ -122,8 +131,8 @@ citext_eq(PG_FUNCTION_ARGS)
/* We can't compare lengths in advance of downcasing ... */
- lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
- rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
+ lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
+ rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
/*
* Since we only care about equality or not-equality, we can avoid all the
@@ -152,8 +161,8 @@ citext_ne(PG_FUNCTION_ARGS)
/* We can't compare lengths in advance of downcasing ... */
- lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
- rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
+ lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
+ rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
/*
* Since we only care about equality or not-equality, we can avoid all the
diff --git a/doc/src/sgml/citext.sgml b/doc/src/sgml/citext.sgml
index 8cbde88a3e..0c6855fea6 100644
--- a/doc/src/sgml/citext.sgml
+++ b/doc/src/sgml/citext.sgml
@@ -58,9 +58,9 @@ SELECT * FROM tab WHERE lower(col) = LOWER(?);
The <type>citext</> data type allows you to eliminate calls
to <function>lower</> in SQL queries, and allows a primary key to
be case-insensitive. <type>citext</> is locale-aware, just
- like <type>text</>, which means that the comparison of upper case and
+ like <type>text</>, which means that the matching of upper case and
lower case characters is dependent on the rules of
- the <literal>LC_CTYPE</> locale setting. Again, this behavior is
+ the database's <literal>LC_CTYPE</> setting. Again, this behavior is
identical to the use of <function>lower</> 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.
@@ -97,17 +97,25 @@ SELECT * FROM users WHERE nick = 'Larry';
<sect2>
<title>String Comparison Behavior</title>
+
+ <para>
+ <type>citext</> performs comparisons by converting each string to lower
+ case (as though <function>lower</> were called) and then comparing the
+ results normally. Thus, for example, two strings are considered equal
+ if <function>lower</> would produce identical results for them.
+ </para>
+
<para>
In order to emulate a case-insensitive collation as closely as possible,
- there are <type>citext</>-specific versions of a number of the comparison
+ there are <type>citext</>-specific versions of a number of string-processing
operators and functions. So, for example, the regular expression
operators <literal>~</> and <literal>~*</> exhibit the same behavior when
- applied to <type>citext</>: they both compare case-insensitively.
+ applied to <type>citext</>: they both match case-insensitively.
The same is true
for <literal>!~</> and <literal>!~*</>, as well as for the
<literal>LIKE</> operators <literal>~~</> and <literal>~~*</>, and
<literal>!~~</> and <literal>!~~*</>. If you'd like to match
- case-sensitively, you can always cast to <type>text</> before comparing.
+ case-sensitively, you can cast the operator's arguments to <type>text</>.
</para>
<para>
@@ -168,10 +176,10 @@ SELECT * FROM users WHERE nick = 'Larry';
<itemizedlist>
<listitem>
<para>
- <type>citext</>'s behavior depends on
+ <type>citext</>'s case-folding behavior depends on
the <literal>LC_CTYPE</> setting of your database. How it compares
- values is therefore determined when
- <application>initdb</> is run to create the cluster. It is not truly
+ 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</>'s comparisons. But
@@ -183,6 +191,20 @@ SELECT * FROM users WHERE nick = 'Larry';
<listitem>
<para>
+ As of <productname>PostgreSQL</> 9.1, you can attach a
+ <literal>COLLATE</> specification to <type>citext</> columns or data
+ values. Currently, <type>citext</> operators will honor a non-default
+ <literal>COLLATE</> specification while comparing case-folded strings,
+ but the initial folding to lower case is always done according to the
+ database's <literal>LC_CTYPE</> setting (that is, as though
+ <literal>COLLATE "default"</> were given). This may be changed in a
+ future release so that both steps follow the input <literal>COLLATE</>
+ specification.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
<type>citext</> is not as efficient as <type>text</> because the
operator functions and the B-tree comparison functions must make copies
of the data and convert it to lower case for comparisons. It is,
@@ -198,11 +220,11 @@ SELECT * FROM users WHERE nick = 'Larry';
contexts. The standard answer is to use the <type>text</> type and
manually use the <function>lower</> 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 most of
- the time and case-sensitive infrequently, consider storing the data
+ 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</> and explicitly casting the column to <type>text</>
- when you want case-sensitive comparison. In either situation, you
- will need two indexes if you want both types of searches to be fast.
+ 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>
@@ -210,8 +232,8 @@ SELECT * FROM users WHERE nick = 'Larry';
<para>
The schema containing the <type>citext</> operators must be
in the current <varname>search_path</> (typically <literal>public</>);
- if it is not, a normal case-sensitive <type>text</> comparison
- is performed.
+ if it is not, the normal case-sensitive <type>text</> operators
+ will be invoked instead.
</para>
</listitem>
</itemizedlist>
diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml
index a60014267e..6df69db4aa 100644
--- a/doc/src/sgml/information_schema.sgml
+++ b/doc/src/sgml/information_schema.sgml
@@ -2159,7 +2159,7 @@
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.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>
@@ -2219,11 +2219,13 @@ ORDER BY c.ordinal_position;
</row>
<row>
- <entry><literal>dtd_identifier</literal></entry>
+ <entry><literal>collection_type_identifier</literal></entry>
<entry><type>sql_identifier</type></entry>
<entry>
The identifier of the data type descriptor of the array being
- described
+ described. Use this to join with the
+ <literal>dtd_identifier</literal> columns of other information
+ schema views.
</entry>
</row>
@@ -2378,6 +2380,14 @@ ORDER BY c.ordinal_position;
<entry>Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</></entry>
</row>
+ <row>
+ <entry><literal>dtd_identifier</literal></entry>
+ <entry><type>sql_identifier</type></entry>
+ <entry>
+ An identifier of the data type descriptor of the element. This
+ is currently not useful.
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml
index 36d7200cb4..ba2646c4c4 100644
--- a/doc/src/sgml/ref/pg_ctl-ref.sgml
+++ b/doc/src/sgml/ref/pg_ctl-ref.sgml
@@ -12,7 +12,7 @@ PostgreSQL documentation
<refnamediv>
<refname>pg_ctl</refname>
- <refpurpose>initialize, start, stop, or restart a <productname>PostgreSQL</productname> server</refpurpose>
+ <refpurpose>initialize, start, stop, or control a <productname>PostgreSQL</productname> server</refpurpose>
</refnamediv>
<indexterm zone="app-pg-ctl">
@@ -77,21 +77,21 @@ PostgreSQL documentation
<cmdsynopsis>
<command>pg_ctl</command>
- <arg choice="plain">promote</arg>
+ <arg choice="plain">reload</arg>
<arg>-s</arg>
<arg>-D <replaceable>datadir</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>pg_ctl</command>
- <arg choice="plain">reload</arg>
- <arg>-s</arg>
+ <arg choice="plain">status</arg>
<arg>-D <replaceable>datadir</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>pg_ctl</command>
- <arg choice="plain">status</arg>
+ <arg choice="plain">promote</arg>
+ <arg>-s</arg>
<arg>-D <replaceable>datadir</replaceable></arg>
</cmdsynopsis>
@@ -191,12 +191,6 @@ PostgreSQL documentation
</para>
<para>
- In <option>promote</option> mode, the standby server that is
- running in the specified data directory is commanded to exit
- recovery and begin read-write operations.
- </para>
-
- <para>
<option>reload</option> mode simply sends the
<command>postgres</command> process a <systemitem>SIGHUP</>
signal, causing it to reread its configuration files
@@ -214,6 +208,12 @@ PostgreSQL documentation
</para>
<para>
+ In <option>promote</option> mode, the standby server that is
+ running in the specified data directory is commanded to exit
+ recovery and begin read-write operations.
+ </para>
+
+ <para>
<option>kill</option> mode allows you to send a signal to a specified
process. This is particularly valuable for <productname>Microsoft Windows</>
which does not have a <application>kill</> command. Use
@@ -397,16 +397,6 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
- <listitem>
- <para>
- User name for the user to start the service. For domain users, use the
- format <literal>DOMAIN\username</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
<term><option>-P <replaceable class="parameter">password</replaceable></option></term>
<listitem>
<para>
@@ -426,6 +416,16 @@ PostgreSQL documentation
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name for the user to start the service. For domain users, use the
+ format <literal>DOMAIN\username</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect2>
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 0418972517..3c5be6bc88 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -143,9 +143,7 @@ coerce_type(ParseState *pstate, Node *node,
}
if (targetTypeId == ANYOID ||
targetTypeId == ANYELEMENTOID ||
- targetTypeId == ANYNONARRAYOID ||
- (targetTypeId == ANYARRAYOID && inputTypeId != UNKNOWNOID) ||
- (targetTypeId == ANYENUMOID && inputTypeId != UNKNOWNOID))
+ targetTypeId == ANYNONARRAYOID)
{
/*
* Assume can_coerce_type verified that implicit coercion is okay.
@@ -154,15 +152,48 @@ coerce_type(ParseState *pstate, Node *node,
* it's OK to treat an UNKNOWN constant as a valid input for a
* function accepting ANY, ANYELEMENT, or ANYNONARRAY. This should be
* all right, since an UNKNOWN value is still a perfectly valid Datum.
- * However an UNKNOWN value is definitely *not* an array, and so we
- * mustn't accept it for ANYARRAY. (Instead, we will call anyarray_in
- * below, which will produce an error.) Likewise, UNKNOWN input is no
- * good for ANYENUM.
*
- * NB: we do NOT want a RelabelType here.
+ * NB: we do NOT want a RelabelType here: the exposed type of the
+ * function argument must be its actual type, not the polymorphic
+ * pseudotype.
*/
return node;
}
+ if (targetTypeId == ANYARRAYOID ||
+ targetTypeId == ANYENUMOID)
+ {
+ /*
+ * Assume can_coerce_type verified that implicit coercion is okay.
+ *
+ * These cases are unlike the ones above because the exposed type of
+ * the argument must be an actual array or enum type. In particular
+ * the argument must *not* be an UNKNOWN constant. If it is, we just
+ * fall through; below, we'll call anyarray_in or anyenum_in, which
+ * will produce an error. Also, if what we have is a domain over
+ * array or enum, we have to relabel it to its base type.
+ *
+ * Note: currently, we can't actually see a domain-over-enum here,
+ * since the other functions in this file will not match such a
+ * parameter to ANYENUM. But that should get changed eventually.
+ */
+ if (inputTypeId != UNKNOWNOID)
+ {
+ Oid baseTypeId = getBaseType(inputTypeId);
+
+ if (baseTypeId != inputTypeId)
+ {
+ RelabelType *r = makeRelabelType((Expr *) node,
+ baseTypeId, -1,
+ InvalidOid,
+ cformat);
+
+ r->location = location;
+ return (Node *) r;
+ }
+ /* Not a domain type, so return it as-is */
+ return node;
+ }
+ }
if (inputTypeId == UNKNOWNOID && IsA(node, Const))
{
/*
@@ -1257,6 +1288,11 @@ coerce_to_common_type(ParseState *pstate, Node *node,
* (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
* is an extra restriction if not.)
*
+ * Domains over arrays match ANYARRAY, and are immediately flattened to their
+ * base type. (Thus, for example, we will consider it a match if one ANYARRAY
+ * argument is a domain over int4[] while another one is just int4[].) Also
+ * notice that such a domain does *not* match ANYNONARRAY.
+ *
* If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
* argument, assume it is okay.
*
@@ -1309,6 +1345,7 @@ check_generic_type_consistency(Oid *actual_arg_types,
{
if (actual_type == UNKNOWNOID)
continue;
+ actual_type = getBaseType(actual_type); /* flatten domains */
if (OidIsValid(array_typeid) && actual_type != array_typeid)
return false;
array_typeid = actual_type;
@@ -1346,8 +1383,8 @@ check_generic_type_consistency(Oid *actual_arg_types,
if (have_anynonarray)
{
- /* require the element type to not be an array */
- if (type_is_array(elem_typeid))
+ /* require the element type to not be an array or domain over array */
+ if (type_is_array_domain(elem_typeid))
return false;
}
@@ -1406,6 +1443,10 @@ check_generic_type_consistency(Oid *actual_arg_types,
* (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
* is an extra restriction if not.)
*
+ * Domains over arrays match ANYARRAY arguments, and are immediately flattened
+ * to their base type. (In particular, if the return type is also ANYARRAY,
+ * we'll set it to the base type not the domain type.)
+ *
* When allow_poly is false, we are not expecting any of the actual_arg_types
* to be polymorphic, and we should not return a polymorphic result type
* either. When allow_poly is true, it is okay to have polymorphic "actual"
@@ -1485,6 +1526,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
}
if (allow_poly && decl_type == actual_type)
continue; /* no new information here */
+ actual_type = getBaseType(actual_type); /* flatten domains */
if (OidIsValid(array_typeid) && actual_type != array_typeid)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -1557,8 +1599,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
if (have_anynonarray && elem_typeid != ANYELEMENTOID)
{
- /* require the element type to not be an array */
- if (type_is_array(elem_typeid))
+ /* require the element type to not be an array or domain over array */
+ if (type_is_array_domain(elem_typeid))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("type matched to anynonarray is an array type: %s",
@@ -1655,15 +1697,19 @@ resolve_generic_type(Oid declared_type,
{
if (context_declared_type == ANYARRAYOID)
{
- /* Use actual type, but it must be an array */
- Oid array_typelem = get_element_type(context_actual_type);
+ /*
+ * Use actual type, but it must be an array; or if it's a domain
+ * over array, use the base array type.
+ */
+ Oid context_base_type = getBaseType(context_actual_type);
+ Oid array_typelem = get_element_type(context_base_type);
if (!OidIsValid(array_typelem))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("argument declared \"anyarray\" is not an array but type %s",
- format_type_be(context_actual_type))));
- return context_actual_type;
+ format_type_be(context_base_type))));
+ return context_base_type;
}
else if (context_declared_type == ANYELEMENTOID ||
context_declared_type == ANYNONARRAYOID ||
@@ -1687,13 +1733,14 @@ resolve_generic_type(Oid declared_type,
if (context_declared_type == ANYARRAYOID)
{
/* Use the element type corresponding to actual type */
- Oid array_typelem = get_element_type(context_actual_type);
+ Oid context_base_type = getBaseType(context_actual_type);
+ Oid array_typelem = get_element_type(context_base_type);
if (!OidIsValid(array_typelem))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("argument declared \"anyarray\" is not an array but type %s",
- format_type_be(context_actual_type))));
+ format_type_be(context_base_type))));
return array_typelem;
}
else if (context_declared_type == ANYELEMENTOID ||
@@ -1796,12 +1843,12 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
/* Also accept any array type as coercible to ANYARRAY */
if (targettype == ANYARRAYOID)
- if (type_is_array(srctype))
+ if (type_is_array_domain(srctype))
return true;
/* Also accept any non-array type as coercible to ANYNONARRAY */
if (targettype == ANYNONARRAYOID)
- if (!type_is_array(srctype))
+ if (!type_is_array_domain(srctype))
return true;
/* Also accept any enum type as coercible to ANYENUM */
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 28da729b6d..7fa649997d 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -729,7 +729,7 @@ OldSerXidInit(void)
/*
* Record a committed read write serializable xid and the minimum
* commitSeqNo of any transactions to which this xid had a rw-conflict out.
- * A zero seqNo means that there were no conflicts out from xid.
+ * An invalid seqNo means that there were no conflicts out from xid.
*/
static void
OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
@@ -807,6 +807,7 @@ OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
slotno = SimpleLruReadPage(OldSerXidSlruCtl, targetPage, true, xid);
OldSerXidValue(slotno, xid) = minConflictCommitSeqNo;
+ OldSerXidSlruCtl->shared->page_dirty[slotno] = true;
LWLockRelease(OldSerXidLock);
}
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index c4b8f15f65..e203c1299d 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -62,9 +62,9 @@ typedef enum
START_COMMAND,
STOP_COMMAND,
RESTART_COMMAND,
- PROMOTE_COMMAND,
RELOAD_COMMAND,
STATUS_COMMAND,
+ PROMOTE_COMMAND,
KILL_COMMAND,
REGISTER_COMMAND,
UNREGISTER_COMMAND,
@@ -126,9 +126,9 @@ static void do_init(void);
static void do_start(void);
static void do_stop(void);
static void do_restart(void);
-static void do_promote(void);
static void do_reload(void);
static void do_status(void);
+static void do_promote(void);
static void do_kill(pgpid_t pid);
static void print_msg(const char *msg);
@@ -922,7 +922,7 @@ do_stop(void)
/*
- * restart/promote/reload routines
+ * restart/reload routines
*/
static void
@@ -1019,6 +1019,43 @@ do_restart(void)
}
static void
+do_reload(void)
+{
+ pgpid_t pid;
+
+ pid = get_pgpid();
+ if (pid == 0) /* no pid file */
+ {
+ write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
+ write_stderr(_("Is server running?\n"));
+ exit(1);
+ }
+ else if (pid < 0) /* standalone backend, not postmaster */
+ {
+ pid = -pid;
+ write_stderr(_("%s: cannot reload server; "
+ "single-user server is running (PID: %ld)\n"),
+ progname, pid);
+ write_stderr(_("Please terminate the single-user server and try again.\n"));
+ exit(1);
+ }
+
+ if (kill((pid_t) pid, sig) != 0)
+ {
+ write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
+ progname, pid, strerror(errno));
+ exit(1);
+ }
+
+ print_msg(_("server signaled\n"));
+}
+
+
+/*
+ * promote
+ */
+
+static void
do_promote(void)
{
FILE *prmfile;
@@ -1079,38 +1116,6 @@ do_promote(void)
}
-static void
-do_reload(void)
-{
- pgpid_t pid;
-
- pid = get_pgpid();
- if (pid == 0) /* no pid file */
- {
- write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
- write_stderr(_("Is server running?\n"));
- exit(1);
- }
- else if (pid < 0) /* standalone backend, not postmaster */
- {
- pid = -pid;
- write_stderr(_("%s: cannot reload server; "
- "single-user server is running (PID: %ld)\n"),
- progname, pid);
- write_stderr(_("Please terminate the single-user server and try again.\n"));
- exit(1);
- }
-
- if (kill((pid_t) pid, sig) != 0)
- {
- write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
- progname, pid, strerror(errno));
- exit(1);
- }
-
- print_msg(_("server signaled\n"));
-}
-
/*
* utility routines
*/
@@ -1732,17 +1737,16 @@ do_advice(void)
static void
do_help(void)
{
- printf(_("%s is a utility to start, stop, restart, promote, reload configuration files,\n"
- "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
+ printf(_("%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n"), progname);
printf(_("Usage:\n"));
printf(_(" %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n"), progname);
printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
" [-o \"OPTIONS\"]\n"), progname);
- printf(_(" %s promote [-D DATADIR] [-s]\n"), progname);
printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
printf(_(" %s status [-D DATADIR]\n"), progname);
+ printf(_(" %s promote [-D DATADIR] [-s]\n"), progname);
printf(_(" %s kill SIGNALNAME PID\n"), progname);
#if defined(WIN32) || defined(__CYGWIN__)
printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
@@ -2066,12 +2070,12 @@ main(int argc, char **argv)
ctl_command = STOP_COMMAND;
else if (strcmp(argv[optind], "restart") == 0)
ctl_command = RESTART_COMMAND;
- else if (strcmp(argv[optind], "promote") == 0)
- ctl_command = PROMOTE_COMMAND;
else if (strcmp(argv[optind], "reload") == 0)
ctl_command = RELOAD_COMMAND;
else if (strcmp(argv[optind], "status") == 0)
ctl_command = STATUS_COMMAND;
+ else if (strcmp(argv[optind], "promote") == 0)
+ ctl_command = PROMOTE_COMMAND;
else if (strcmp(argv[optind], "kill") == 0)
{
if (argc - optind < 3)
@@ -2174,12 +2178,12 @@ main(int argc, char **argv)
case RESTART_COMMAND:
do_restart();
break;
- case PROMOTE_COMMAND:
- do_promote();
- break;
case RELOAD_COMMAND:
do_reload();
break;
+ case PROMOTE_COMMAND:
+ do_promote();
+ break;
case KILL_COMMAND:
do_kill(killproc);
break;
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 1f44acb9d3..7484d65b32 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -127,6 +127,16 @@ select testint4arr[1], testchar4arr[2:2] from domarrtest;
| {{d,e,f}}
(5 rows)
+select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest;
+ array_dims | array_dims
+------------+------------
+ [1:2] | [1:2][1:2]
+ [1:2][1:2] | [1:1][1:2]
+ [1:2] | [1:3][1:2]
+ [1:2] | [1:2][1:1]
+ | [1:2][1:3]
+(5 rows)
+
COPY domarrtest FROM stdin;
COPY domarrtest FROM stdin; -- fail
ERROR: value too long for type character varying(4)
@@ -146,6 +156,32 @@ select * from domarrtest;
drop table domarrtest;
drop domain domainint4arr restrict;
drop domain domainchar4arr restrict;
+create domain dia as int[];
+select '{1,2,3}'::dia;
+ dia
+---------
+ {1,2,3}
+(1 row)
+
+select array_dims('{1,2,3}'::dia);
+ array_dims
+------------
+ [1:3]
+(1 row)
+
+select pg_typeof('{1,2,3}'::dia);
+ pg_typeof
+-----------
+ dia
+(1 row)
+
+select pg_typeof('{1,2,3}'::dia || 42); -- should be int[] not dia
+ pg_typeof
+-----------
+ integer[]
+(1 row)
+
+drop domain dia;
create domain dnotnull varchar(15) NOT NULL;
create domain dnull varchar(15);
create domain dcheck varchar(15) NOT NULL CHECK (VALUE = 'a' OR VALUE = 'c' OR VALUE = 'd');
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index 4da4fd5043..c3ad7ebca3 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -87,6 +87,7 @@ INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}');
select * from domarrtest;
select testint4arr[1], testchar4arr[2:2] from domarrtest;
+select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest;
COPY domarrtest FROM stdin;
{3,4} {q,w,e}
@@ -103,6 +104,12 @@ drop table domarrtest;
drop domain domainint4arr restrict;
drop domain domainchar4arr restrict;
+create domain dia as int[];
+select '{1,2,3}'::dia;
+select array_dims('{1,2,3}'::dia);
+select pg_typeof('{1,2,3}'::dia);
+select pg_typeof('{1,2,3}'::dia || 42); -- should be int[] not dia
+drop domain dia;
create domain dnotnull varchar(15) NOT NULL;
create domain dnull varchar(15);