diff options
author | Bernd Helmle | 2011-06-09 15:01:11 +0000 |
---|---|---|
committer | Bernd Helmle | 2011-06-09 15:01:11 +0000 |
commit | 4f01eeaad0c058a9717ced354cacccce4c52f488 (patch) | |
tree | 6f5309ced89ed722ea28b6b90a3a93d8da063d4e | |
parent | 5fd3024a3d606946063ffa2ffce0e9167e3f3ec4 (diff) | |
parent | 5234161ac10350e009874e4872935a6133d8f0fc (diff) |
Merge branch 'master' of ../bernd_pg into notnull_constraint
-rw-r--r-- | contrib/citext/citext.c | 23 | ||||
-rw-r--r-- | doc/src/sgml/citext.sgml | 50 | ||||
-rw-r--r-- | doc/src/sgml/information_schema.sgml | 16 | ||||
-rw-r--r-- | doc/src/sgml/ref/pg_ctl-ref.sgml | 42 | ||||
-rw-r--r-- | src/backend/parser/parse_coerce.c | 87 | ||||
-rw-r--r-- | src/backend/storage/lmgr/predicate.c | 3 | ||||
-rw-r--r-- | src/bin/pg_ctl/pg_ctl.c | 90 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 36 | ||||
-rw-r--r-- | src/test/regress/sql/domain.sql | 7 |
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); |