Re: [HACKERS] Regression tests vs existing users in an installation - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: [HACKERS] Regression tests vs existing users in an installation |
Date | |
Msg-id | 3606.1561747369@sss.pgh.pa.us Whole thread Raw |
In response to | Re: [HACKERS] Regression tests vs existing users in an installation (Stephen Frost <sfrost@snowman.net>) |
List | pgsql-hackers |
OK, here's a completed patch to add checking for naming-rule violations. I updated regress.sgml to clarify the naming rules (and failed to resist the temptation to update a lot of other somewhat-obsolete statements there, too). Also worth noting is that I added an IsReservedName check to pg_replication_origin_create(), ie it will no longer allow user-selected origin names starting with "pg_". This seems like a good idea considering that we generate internal origin names that look like that. I have not done anything equivalent for subscription names, but should we consider doing so? I touched the TAP tests only to the extent necessary to make them pass cleanly --- mostly I had to fool with pg_dump/t/010_dump_connstr.pl because it whines if the restore step emits any warnings. Perhaps there's another way to address that with less invasive changes to that test script; but I couldn't think of one other than ignoring warnings, which didn't seem like a great idea. This patch doesn't address the issue that we think rolenames.sql is unsafe to run in "make installcheck" mode. That seems like a separable problem, and we'd have to adjust that script as shown here anyway. Barring objections, I'll push this shortly (to HEAD only) and turn on the enabling switch on one or two of my buildfarm critters. regards, tom lane diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index 448e2d1..7b68213 100644 --- a/doc/src/sgml/regress.sgml +++ b/doc/src/sgml/regress.sgml @@ -47,7 +47,7 @@ make check <screen> <computeroutput> ======================= - All 115 tests passed. + All 193 tests passed. ======================= </computeroutput> </screen> @@ -98,7 +98,7 @@ make MAX_CONNECTIONS=10 check <para> To run the tests after installation (see <xref linkend="installation"/>), - initialize a data area and start the + initialize a data directory and start the server as explained in <xref linkend="runtime"/>, then type: <screen> make installcheck @@ -116,10 +116,10 @@ make installcheck-parallel <para> The tests will also transiently create some cluster-wide objects, such as - roles and tablespaces. These objects will have names beginning with - <literal>regress_</literal>. Beware of using <literal>installcheck</literal> - mode in installations that have any actual users or tablespaces named - that way. + roles, tablespaces, and subscriptions. These objects will have names + beginning with <literal>regress_</literal>. Beware of + using <literal>installcheck</literal> mode with an installation that has + any actual global objects named that way. </para> </sect2> @@ -130,7 +130,7 @@ make installcheck-parallel The <literal>make check</literal> and <literal>make installcheck</literal> commands run only the <quote>core</quote> regression tests, which test built-in functionality of the <productname>PostgreSQL</productname> server. The source - distribution also contains additional test suites, most of them having + distribution contains many additional test suites, most of them having to do with add-on functionality such as optional procedural languages. </para> @@ -146,9 +146,24 @@ make installcheck-world already-installed server, respectively, just as previously explained for <literal>make check</literal> and <literal>make installcheck</literal>. Other considerations are the same as previously explained for each method. - Note that <literal>make check-world</literal> builds a separate temporary - installation tree for each tested module, so it requires a great deal - more time and disk space than <literal>make installcheck-world</literal>. + Note that <literal>make check-world</literal> builds a separate instance + (temporary data directory) for each tested module, so it requires more + time and disk space than <literal>make installcheck-world</literal>. + </para> + + <para> + On a modern machine with multiple CPU cores and no tight operating-system + limits, you can make things go substantially faster with parallelism. + The recipe that most PostgreSQL developers actually use for running all + tests is something like +<screen> +make check-world -j8 >/dev/null +</screen> + with a <option>-j</option> limit near to or a bit more than the number + of available cores. Discarding <systemitem>stdout</systemitem> + eliminates chatter that's not interesting when you just want to verify + success. (In case of failure, the <systemitem>stderr</systemitem> + messages are usually enough to determine where to look closer.) </para> <para> @@ -166,8 +181,7 @@ make installcheck-world <itemizedlist> <listitem> <para> - Regression tests for optional procedural languages (other than - <application>PL/pgSQL</application>, which is tested by the core tests). + Regression tests for optional procedural languages. These are located under <filename>src/pl</filename>. </para> </listitem> @@ -186,27 +200,49 @@ make installcheck-world </listitem> <listitem> <para> + Tests for core-supported authentication methods, + located in <filename>src/test/authentication</filename>. + (See below for additional authentication-related tests.) + </para> + </listitem> + <listitem> + <para> Tests stressing behavior of concurrent sessions, located in <filename>src/test/isolation</filename>. </para> </listitem> <listitem> <para> - Tests of client programs under <filename>src/bin</filename>. See - also <xref linkend="regress-tap"/>. + Tests for crash recovery and physical replication, + located in <filename>src/test/recovery</filename>. + </para> + </listitem> + <listitem> + <para> + Tests for logical replication, + located in <filename>src/test/subscription</filename>. + </para> + </listitem> + <listitem> + <para> + Tests of client programs, located under <filename>src/bin</filename>. </para> </listitem> </itemizedlist> <para> - When using <literal>installcheck</literal> mode, these tests will destroy any - existing databases named <literal>pl_regression</literal>, - <literal>contrib_regression</literal>, <literal>isolation_regression</literal>, - <literal>ecpg1_regression</literal>, or <literal>ecpg2_regression</literal>, as well as - <literal>regression</literal>. + When using <literal>installcheck</literal> mode, these tests will create + and destroy test databases whose names + include <literal>regression</literal>, for + example <literal>pl_regression</literal> + or <literal>contrib_regression</literal>. Beware of + using <literal>installcheck</literal> mode with an installation that has + any non-test databases named that way. </para> <para> + Some of these auxiliary test suites use the TAP infrastructure explained + in <xref linkend="regress-tap"/>. The TAP-based tests are run only when PostgreSQL was configured with the option <option>--enable-tap-tests</option>. This is recommended for development, but can be omitted if there is no suitable Perl installation. @@ -259,6 +295,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl' configuration are not run even if they are mentioned in <varname>PG_TEST_EXTRA</varname>. </para> + + <para> + In addition, there are tests in <filename>src/test/modules</filename> + which will be run by <literal>make check-world</literal> but not + by <literal>make installcheck-world</literal>. This is because they + install non-production extensions or have other side-effects that are + considered undesirable for a production installation. You can + use <literal>make install</literal> and <literal>make + installcheck</literal> in one of those subdirectories if you wish, + but it's not recommended to do so with a non-test server. + </para> </sect2> <sect2> @@ -737,6 +784,26 @@ make check PROVE_TESTS='t/001_test1.pl t/003_test3.pl' The TAP tests require the Perl module <literal>IPC::Run</literal>. This module is available from CPAN or an operating system package. </para> + + <para> + Generically speaking, the TAP tests will test the executables in a + previously-installed installation tree if you say <literal>make + installcheck</literal>, or will build a new local installation tree from + current sources if you say <literal>make check</literal>. In either + case they will initialize a local instance (data directory) and + transiently run a server in it. Some of these tests run more than one + server. Thus, these tests can be fairly resource-intensive. + </para> + + <para> + It's important to realize that the TAP tests will start test server(s) + even when you say <literal>make installcheck</literal>; this is unlike + the traditional non-TAP testing infrastructure, which expects to use an + already-running test server in that case. Some PostgreSQL + subdirectories contain both traditional-style and TAP-style tests, + meaning that <literal>make installcheck</literal> will produce a mix of + results from temporary servers and the already-running test server. + </para> </sect1> <sect1 id="regress-coverage"> diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 9229fe1..70dbcb0 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -274,6 +274,12 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) if (SearchSysCacheExists2(SUBSCRIPTIONNAME, MyDatabaseId, CStringGetDatum(new_name))) report_name_conflict(classId, new_name); + + /* Also enforce regression testing naming rules, if enabled */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(new_name, "regress_", 8) != 0) + elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\""); +#endif } else if (nameCacheId >= 0) { diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 15207bf..863f89f 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -471,6 +471,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) } /* + * If built with appropriate switch, whine when regression-testing + * conventions for database names are violated. But don't complain during + * initdb. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (IsUnderPostmaster && strstr(dbname, "regression") == NULL) + elog(WARNING, "databases created by regression test cases should have names including \"regression\""); +#endif + + /* * Check for db name conflict. This is just to give a more friendly error * message than "unique index violation". There's a race condition but * we're willing to accept the less friendly message in that case. @@ -1009,6 +1019,15 @@ RenameDatabase(const char *oldname, const char *newname) errmsg("permission denied to rename database"))); /* + * If built with appropriate switch, whine when regression-testing + * conventions for database names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strstr(newname, "regression") == NULL) + elog(WARNING, "databases created by regression test cases should have names including \"regression\""); +#endif + + /* * Make sure the new name doesn't exist. See notes for same error in * CREATE DATABASE. */ diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index f13dce9..2e67a58 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -357,6 +357,15 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to create subscriptions")))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for subscription names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->subname, "regress_", 8) != 0) + elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\""); +#endif + rel = table_open(SubscriptionRelationId, RowExclusiveLock); /* Check if name is used */ diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 5e43867..502736b 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -308,6 +308,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) errdetail("The prefix \"pg_\" is reserved for system tablespaces."))); /* + * If built with appropriate switch, whine when regression-testing + * conventions for tablespace names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->tablespacename, "regress_", 8) != 0) + elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\""); +#endif + + /* * Check that there is no other tablespace by this name. (The unique * index would catch this anyway, but might as well give a friendlier * message.) @@ -957,6 +966,15 @@ RenameTableSpace(const char *oldname, const char *newname) errmsg("unacceptable tablespace name \"%s\"", newname), errdetail("The prefix \"pg_\" is reserved for system tablespaces."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for tablespace names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(newname, "regress_", 8) != 0) + elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\""); +#endif + /* Make sure the new name doesn't exist */ ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index ccc586d..aab5aa8 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -327,6 +327,15 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) errdetail("Role names starting with \"pg_\" are reserved."))); /* + * If built with appropriate switch, whine when regression-testing + * conventions for role names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->role, "regress_", 8) != 0) + elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\""); +#endif + + /* * Check the pg_authid relation to be certain the role doesn't already * exist. */ @@ -1212,6 +1221,15 @@ RenameRole(const char *oldname, const char *newname) newname), errdetail("Role names starting with \"pg_\" are reserved."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for role names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(newname, "regress_", 8) != 0) + elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\""); +#endif + /* make sure the new name doesn't exist */ if (SearchSysCacheExists1(AUTHNAME, CStringGetDatum(newname))) ereport(ERROR, diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index ff4d54d..681132c 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -78,6 +78,7 @@ #include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/indexing.h" #include "nodes/execnodes.h" @@ -1228,6 +1229,24 @@ pg_replication_origin_create(PG_FUNCTION_ARGS) replorigin_check_prerequisites(false, false); name = text_to_cstring((text *) DatumGetPointer(PG_GETARG_DATUM(0))); + + /* Replication origins "pg_xxx" are reserved for internal use */ + if (IsReservedName(name)) + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("replication origin name \"%s\" is reserved", + name), + errdetail("Origin names starting with \"pg_\" are reserved."))); + + /* + * If built with appropriate switch, whine when regression-testing + * conventions for replication origin names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(name, "regress_", 8) != 0) + elog(WARNING, "replication origins created by regression test cases should have names starting with \"regress_\""); +#endif + roident = replorigin_create(name); pfree(name); diff --git a/src/test/modules/README b/src/test/modules/README index 99f921d..025ecac 100644 --- a/src/test/modules/README +++ b/src/test/modules/README @@ -6,6 +6,13 @@ intended for testing PostgreSQL and/or to serve as example code. The extensions here aren't intended to be installed in a production server and aren't suitable for "real work". +Furthermore, while you can do "make install" and "make installcheck" in +this directory or its children, it is NOT ADVISABLE to do so with a server +containing valuable data. Some of these tests may have undesirable +side-effects on roles or other global objects within the tested server. +"make installcheck-world" at the top level does not recurse into this +directory. + Most extensions have their own pg_regress tests or isolationtester specs. Some are also used by tests elsewhere in the tree. diff --git a/contrib/test_decoding/expected/replorigin.out b/contrib/test_decoding/expected/replorigin.out index 8ea4ddd..3b249f4 100644 --- a/contrib/test_decoding/expected/replorigin.out +++ b/contrib/test_decoding/expected/replorigin.out @@ -2,38 +2,38 @@ SET synchronous_commit = on; CREATE TABLE origin_tbl(id serial primary key, data text); CREATE TABLE target_tbl(id serial primary key, data text); -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); pg_replication_origin_create ------------------------------ 1 (1 row) -- ensure duplicate creations fail -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); ERROR: duplicate key value violates unique constraint "pg_replication_origin_roname_index" -DETAIL: Key (roname)=(test_decoding: regression_slot) already exists. +DETAIL: Key (roname)=(regress_test_decoding: regression_slot) already exists. --ensure deletions work (once) -SELECT pg_replication_origin_create('test_decoding: temp'); +SELECT pg_replication_origin_create('regress_test_decoding: temp'); pg_replication_origin_create ------------------------------ 2 (1 row) -SELECT pg_replication_origin_drop('test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); pg_replication_origin_drop ---------------------------- (1 row) -SELECT pg_replication_origin_drop('test_decoding: temp'); -ERROR: replication origin "test_decoding: temp" does not exist +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); +ERROR: replication origin "regress_test_decoding: temp" does not exist -- various failure checks for undefined slots -select pg_replication_origin_advance('test_decoding: temp', '0/1'); -ERROR: replication origin "test_decoding: temp" does not exist -select pg_replication_origin_session_setup('test_decoding: temp'); -ERROR: replication origin "test_decoding: temp" does not exist -select pg_replication_origin_progress('test_decoding: temp', true); -ERROR: replication origin "test_decoding: temp" does not exist +select pg_replication_origin_advance('regress_test_decoding: temp', '0/1'); +ERROR: replication origin "regress_test_decoding: temp" does not exist +select pg_replication_origin_session_setup('regress_test_decoding: temp'); +ERROR: replication origin "regress_test_decoding: temp" does not exist +select pg_replication_origin_progress('regress_test_decoding: temp', true); +ERROR: replication origin "regress_test_decoding: temp" does not exist SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); ?column? ---------- @@ -57,14 +57,14 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again'); -- mark session as replaying -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); pg_replication_origin_session_setup ------------------------------------- (1 row) -- ensure we prevent duplicate setup -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); ERROR: cannot setup replication origin when one is already setup SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded'); ?column? @@ -103,19 +103,19 @@ SELECT pg_replication_origin_session_reset(); (1 row) SELECT local_id, external_id, remote_lsn, local_lsn <> '0/0' FROM pg_replication_origin_status; - local_id | external_id | remote_lsn | ?column? -----------+--------------------------------+------------+---------- - 1 | test_decoding: regression_slot | 0/AABBCCDD | t + local_id | external_id | remote_lsn | ?column? +----------+----------------------------------------+------------+---------- + 1 | regress_test_decoding: regression_slot | 0/AABBCCDD | t (1 row) -- check replication progress identified by name is correct -SELECT pg_replication_origin_progress('test_decoding: regression_slot', false); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', false); pg_replication_origin_progress -------------------------------- 0/AABBCCDD (1 row) -SELECT pg_replication_origin_progress('test_decoding: regression_slot', true); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', true); pg_replication_origin_progress -------------------------------- 0/AABBCCDD @@ -146,7 +146,7 @@ SELECT pg_drop_replication_slot('regression_slot'); (1 row) -SELECT pg_replication_origin_drop('test_decoding: regression_slot'); +SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); pg_replication_origin_drop ---------------------------- diff --git a/contrib/test_decoding/expected/rewrite.out b/contrib/test_decoding/expected/rewrite.out index 28998b8..b30999c 100644 --- a/contrib/test_decoding/expected/rewrite.out +++ b/contrib/test_decoding/expected/rewrite.out @@ -11,7 +11,7 @@ CREATE FUNCTION exec(text) returns void language plpgsql volatile EXECUTE $1; END; $f$; -CREATE ROLE justforcomments NOLOGIN; +CREATE ROLE regress_justforcomments NOLOGIN; SELECT exec( format($outer$CREATE FUNCTION iamalongfunction() RETURNS TEXT IMMUTABLE LANGUAGE SQL AS $f$SELECT text %L$f$$outer$, (SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i)))); @@ -29,7 +29,7 @@ SELECT exec( (1 row) SELECT exec( - format($outer$COMMENT ON ROLE JUSTFORCOMMENTS IS %L$outer$, + format($outer$COMMENT ON ROLE REGRESS_JUSTFORCOMMENTS IS %L$outer$, iamalongfunction())); exec ------ @@ -161,4 +161,4 @@ SELECT pg_drop_replication_slot('regression_slot'); DROP TABLE IF EXISTS replication_example; DROP FUNCTION iamalongfunction(); DROP FUNCTION exec(text); -DROP ROLE justforcomments; +DROP ROLE regress_justforcomments; diff --git a/contrib/test_decoding/sql/replorigin.sql b/contrib/test_decoding/sql/replorigin.sql index 451cd4b..8979b30 100644 --- a/contrib/test_decoding/sql/replorigin.sql +++ b/contrib/test_decoding/sql/replorigin.sql @@ -4,19 +4,19 @@ SET synchronous_commit = on; CREATE TABLE origin_tbl(id serial primary key, data text); CREATE TABLE target_tbl(id serial primary key, data text); -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); -- ensure duplicate creations fail -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); --ensure deletions work (once) -SELECT pg_replication_origin_create('test_decoding: temp'); -SELECT pg_replication_origin_drop('test_decoding: temp'); -SELECT pg_replication_origin_drop('test_decoding: temp'); +SELECT pg_replication_origin_create('regress_test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); -- various failure checks for undefined slots -select pg_replication_origin_advance('test_decoding: temp', '0/1'); -select pg_replication_origin_session_setup('test_decoding: temp'); -select pg_replication_origin_progress('test_decoding: temp', true); +select pg_replication_origin_advance('regress_test_decoding: temp', '0/1'); +select pg_replication_origin_session_setup('regress_test_decoding: temp'); +select pg_replication_origin_progress('regress_test_decoding: temp', true); SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); @@ -31,10 +31,10 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again'); -- mark session as replaying -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); -- ensure we prevent duplicate setup -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded'); @@ -54,8 +54,8 @@ SELECT pg_replication_origin_session_reset(); SELECT local_id, external_id, remote_lsn, local_lsn <> '0/0' FROM pg_replication_origin_status; -- check replication progress identified by name is correct -SELECT pg_replication_origin_progress('test_decoding: regression_slot', false); -SELECT pg_replication_origin_progress('test_decoding: regression_slot', true); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', false); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', true); -- ensure reset requires previously setup state SELECT pg_replication_origin_session_reset(); @@ -68,4 +68,4 @@ INSERT INTO origin_tbl(data) VALUES ('will be replicated'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'only-local', '1'); SELECT pg_drop_replication_slot('regression_slot'); -SELECT pg_replication_origin_drop('test_decoding: regression_slot'); +SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); diff --git a/contrib/test_decoding/sql/rewrite.sql b/contrib/test_decoding/sql/rewrite.sql index c9503a0..62dead3 100644 --- a/contrib/test_decoding/sql/rewrite.sql +++ b/contrib/test_decoding/sql/rewrite.sql @@ -13,7 +13,7 @@ CREATE FUNCTION exec(text) returns void language plpgsql volatile EXECUTE $1; END; $f$; -CREATE ROLE justforcomments NOLOGIN; +CREATE ROLE regress_justforcomments NOLOGIN; SELECT exec( format($outer$CREATE FUNCTION iamalongfunction() RETURNS TEXT IMMUTABLE LANGUAGE SQL AS $f$SELECT text %L$f$$outer$, @@ -22,7 +22,7 @@ SELECT exec( format($outer$COMMENT ON FUNCTION iamalongfunction() IS %L$outer$, iamalongfunction())); SELECT exec( - format($outer$COMMENT ON ROLE JUSTFORCOMMENTS IS %L$outer$, + format($outer$COMMENT ON ROLE REGRESS_JUSTFORCOMMENTS IS %L$outer$, iamalongfunction())); CREATE TABLE iamalargetable AS SELECT iamalongfunction() longfunctionoutput; @@ -104,4 +104,4 @@ SELECT pg_drop_replication_slot('regression_slot'); DROP TABLE IF EXISTS replication_example; DROP FUNCTION iamalongfunction(); DROP FUNCTION exec(text); -DROP ROLE justforcomments; +DROP ROLE regress_justforcomments; diff --git a/src/bin/pg_dump/t/010_dump_connstr.pl b/src/bin/pg_dump/t/010_dump_connstr.pl index 28a9eb7..d221682 100644 --- a/src/bin/pg_dump/t/010_dump_connstr.pl +++ b/src/bin/pg_dump/t/010_dump_connstr.pl @@ -22,29 +22,42 @@ $ENV{PGCLIENTENCODING} = 'LATIN1'; # Create database and user names covering the range of LATIN1 # characters, for use in a connection string by pg_dumpall. Skip ',' # because of pg_regress --create-role, skip [\n\r] because pg_dumpall -# does not allow them. +# does not allow them. We also skip many ASCII letters, to keep the +# total number of tested characters to what will fit in four names. +# The odds of finding something interesting by testing all ASCII letters +# seem too small to justify the cycles of testing a fifth name. my $dbname1 = - generate_ascii_string(1, 9) + 'regression' + . generate_ascii_string(1, 9) . generate_ascii_string(11, 12) . generate_ascii_string(14, 33) - . ($TestLib::windows_os ? '' : '"x"') - . # IPC::Run mishandles '"' on Windows - generate_ascii_string(35, 43) - . generate_ascii_string(45, 63); # contains '=' -my $dbname2 = - generate_ascii_string(67, 129); # skip 64-66 to keep length to 62 -my $dbname3 = generate_ascii_string(130, 192); -my $dbname4 = generate_ascii_string(193, 255); + . ($TestLib::windows_os ? '' : '"x"') # IPC::Run mishandles '"' on Windows + . generate_ascii_string(35, 43) # skip ',' + . generate_ascii_string(45, 54); +my $dbname2 = 'regression' . generate_ascii_string(55, 65) # skip 'B'-'W' + . generate_ascii_string(88, 99) # skip 'd'-'w' + . generate_ascii_string(120, 149); +my $dbname3 = 'regression' . generate_ascii_string(150, 202); +my $dbname4 = 'regression' . generate_ascii_string(203, 255); + +(my $username1 = $dbname1) =~ s/^regression/regress_/; +(my $username2 = $dbname2) =~ s/^regression/regress_/; +(my $username3 = $dbname3) =~ s/^regression/regress_/; +(my $username4 = $dbname4) =~ s/^regression/regress_/; + +my $src_bootstrap_super = 'regress_postgres'; +my $dst_bootstrap_super = 'boot'; my $node = get_new_node('main'); -$node->init(extra => [ '--locale=C', '--encoding=LATIN1' ]); +$node->init(extra => + [ '-U', $src_bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); # prep pg_hba.conf and pg_ident.conf $node->run_log( [ $ENV{PG_REGRESS}, '--config-auth', $node->data_dir, '--create-role', - "$dbname1,$dbname2,$dbname3,$dbname4" + "$username1,$username2,$username3,$username4" ]); $node->start; @@ -53,11 +66,18 @@ my $discard = "$backupdir/discard.sql"; my $plain = "$backupdir/plain.sql"; my $dirfmt = "$backupdir/dirfmt"; -foreach my $dbname ($dbname1, $dbname2, $dbname3, $dbname4, 'CamelCase') -{ - $node->run_log([ 'createdb', $dbname ]); - $node->run_log([ 'createuser', '-s', $dbname ]); -} +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname1 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username1 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname2 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username2 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname3 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username3 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname4 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username4 ]); # For these tests, pg_dumpall -r is used because it produces a short @@ -66,98 +86,109 @@ $node->command_ok( [ 'pg_dumpall', '-r', '-f', $discard, '--dbname', $node->connstr($dbname1), - '-U', $dbname4 + '-U', $username4 ], 'pg_dumpall with long ASCII name 1'); $node->command_ok( [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname2), - '-U', $dbname3 + '-U', $username3 ], 'pg_dumpall with long ASCII name 2'); $node->command_ok( [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname3), - '-U', $dbname2 + '-U', $username2 ], 'pg_dumpall with long ASCII name 3'); $node->command_ok( [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname4), - '-U', $dbname1 + '-U', $username1 ], 'pg_dumpall with long ASCII name 4'); $node->command_ok( - [ 'pg_dumpall', '--no-sync', '-r', '-l', 'dbname=template1' ], + [ + 'pg_dumpall', '-U', + $src_bootstrap_super, '--no-sync', + '-r', '-l', + 'dbname=template1' + ], 'pg_dumpall -l accepts connection string'); -$node->run_log([ 'createdb', "foo\n\rbar" ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, "foo\n\rbar" ]); # not sufficient to use -r here $node->command_fails( - [ 'pg_dumpall', '--no-sync', '-f', $discard ], + [ 'pg_dumpall', '-U', $src_bootstrap_super, '--no-sync', '-f', $discard ], 'pg_dumpall with \n\r in database name'); -$node->run_log([ 'dropdb', "foo\n\rbar" ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, "foo\n\rbar" ]); # make a table, so the parallel worker has something to dump -$node->safe_psql($dbname1, 'CREATE TABLE t0()'); +$node->safe_psql( + $dbname1, + 'CREATE TABLE t0()', + extra_params => [ '-U', $src_bootstrap_super ]); # XXX no printed message when this fails, just SIGPIPE termination $node->command_ok( [ - 'pg_dump', '-Fd', '--no-sync', '-j2', '-f', $dirfmt, '-U', $dbname1, + 'pg_dump', '-Fd', '--no-sync', '-j2', '-f', $dirfmt, '-U', $username1, $node->connstr($dbname1) ], 'parallel dump'); # recreate $dbname1 for restore test -$node->run_log([ 'dropdb', $dbname1 ]); -$node->run_log([ 'createdb', $dbname1 ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, $dbname1 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname1 ]); $node->command_ok( - [ 'pg_restore', '-v', '-d', 'template1', '-j2', '-U', $dbname1, $dirfmt ], + [ + 'pg_restore', '-v', '-d', 'template1', + '-j2', '-U', $username1, $dirfmt + ], 'parallel restore'); -$node->run_log([ 'dropdb', $dbname1 ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, $dbname1 ]); $node->command_ok( [ 'pg_restore', '-C', '-v', '-d', - 'template1', '-j2', '-U', $dbname1, + 'template1', '-j2', '-U', $username1, $dirfmt ], 'parallel restore with create'); -$node->command_ok([ 'pg_dumpall', '--no-sync', '-f', $plain, '-U', $dbname1 ], +$node->command_ok( + [ 'pg_dumpall', '--no-sync', '-f', $plain, '-U', $username1 ], 'take full dump'); system_log('cat', $plain); my ($stderr, $result); -my $bootstrap_super = 'boot'; -my $restore_super = qq{a'b\\c=d\\ne"f}; +my $restore_super = qq{regress_a'b\\c=d\\ne"f}; # Restore full dump through psql using environment variables for # dbname/user connection parameters my $envar_node = get_new_node('destination_envar'); -$envar_node->init( - extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); +$envar_node->init(extra => + [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); $envar_node->run_log( [ $ENV{PG_REGRESS}, '--config-auth', $envar_node->data_dir, '--create-role', - "$bootstrap_super,$restore_super" + "$dst_bootstrap_super,$restore_super" ]); $envar_node->start; # make superuser for restore $envar_node->run_log( - [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); + [ 'createuser', '-U', $dst_bootstrap_super, '-s', $restore_super ]); { local $ENV{PGPORT} = $envar_node->port; @@ -177,17 +208,17 @@ is($stderr, '', 'no dump errors'); $restore_super =~ s/"//g if $TestLib::windows_os; # IPC::Run mishandles '"' on Windows my $cmdline_node = get_new_node('destination_cmdline'); -$cmdline_node->init( - extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); +$cmdline_node->init(extra => + [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); $cmdline_node->run_log( [ $ENV{PG_REGRESS}, '--config-auth', $cmdline_node->data_dir, '--create-role', - "$bootstrap_super,$restore_super" + "$dst_bootstrap_super,$restore_super" ]); $cmdline_node->start; $cmdline_node->run_log( - [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); + [ 'createuser', '-U', $dst_bootstrap_super, '-s', $restore_super ]); { $result = run_log( [ diff --git a/src/bin/pg_upgrade/test.sh b/src/bin/pg_upgrade/test.sh index d6d196a..7882024 100644 --- a/src/bin/pg_upgrade/test.sh +++ b/src/bin/pg_upgrade/test.sh @@ -159,9 +159,9 @@ dbname1=`awk 'BEGIN { for (i= 1; i < 46; i++) dbname1='\"\'$dbname1'\\"\\\' dbname2=`awk 'BEGIN { for (i = 46; i < 91; i++) printf "%c", i }' </dev/null` dbname3=`awk 'BEGIN { for (i = 91; i < 128; i++) printf "%c", i }' </dev/null` -createdb "$dbname1" || createdb_status=$? -createdb "$dbname2" || createdb_status=$? -createdb "$dbname3" || createdb_status=$? +createdb "regression$dbname1" || createdb_status=$? +createdb "regression$dbname2" || createdb_status=$? +createdb "regression$dbname3" || createdb_status=$? if "$MAKE" -C "$oldsrc" installcheck-parallel; then oldpgversion=`psql -X -A -t -d regression -c "SHOW server_version_num"` diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index 88ae9e7..de75b9a 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -43,7 +43,7 @@ CREATE TRANSFORM FOR int LANGUAGE SQL ( FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; -CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; -- test some error cases @@ -425,7 +425,7 @@ WITH objects (type, name, args) AS (VALUES ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), - ('subscription', '{addr_sub}', '{}'), + ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') ) SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, @@ -484,7 +484,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, text search parser | addr_nsp | addr_ts_prs | addr_nsp.addr_ts_prs | t text search configuration | addr_nsp | addr_ts_conf | addr_nsp.addr_ts_conf | t text search template | addr_nsp | addr_ts_temp | addr_nsp.addr_ts_temp | t - subscription | | addr_sub | addr_sub | t + subscription | | regress_addr_sub | regress_addr_sub | t publication | | addr_pub | addr_pub | t publication relation | | | addr_nsp.gentable in publication addr_pub | t (49 rows) @@ -499,7 +499,7 @@ drop cascades to foreign table genftable drop cascades to server integer drop cascades to user mapping for regress_addr_user on server integer DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub; +DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; NOTICE: drop cascades to 14 other objects DETAIL: drop cascades to text search dictionary addr_ts_dict diff --git a/src/test/regress/expected/rolenames.out b/src/test/regress/expected/rolenames.out index 6d2b524..03c1a25 100644 --- a/src/test/regress/expected/rolenames.out +++ b/src/test/regress/expected/rolenames.out @@ -37,11 +37,19 @@ SELECT r.rolname, s.srvname, m.umoptions JOIN pg_foreign_server s ON (s.oid = m.umserver) ORDER BY 2; $$ LANGUAGE SQL; +-- +-- We test creation and use of these role names to ensure that the server +-- correctly distinguishes role keywords from quoted names that look like +-- those keywords. In a test environment, creation of these roles may +-- provoke warnings, so hide the warnings by raising client_min_messages. +-- +SET client_min_messages = ERROR; CREATE ROLE "Public"; CREATE ROLE "None"; CREATE ROLE "current_user"; CREATE ROLE "session_user"; CREATE ROLE "user"; +RESET client_min_messages; CREATE ROLE current_user; -- error ERROR: CURRENT_USER cannot be used as a role name here LINE 1: CREATE ROLE current_user; diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 5ec3b40..e7add9d 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -6,31 +6,31 @@ CREATE ROLE regress_subscription_user2; CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - no publications -CREATE SUBSCRIPTION testsub CONNECTION 'foo'; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; ERROR: syntax error at or near ";" -LINE 1: CREATE SUBSCRIPTION testsub CONNECTION 'foo'; - ^ +LINE 1: CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; + ^ -- fail - no connection -CREATE SUBSCRIPTION testsub PUBLICATION foo; +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; ERROR: syntax error at or near "PUBLICATION" -LINE 1: CREATE SUBSCRIPTION testsub PUBLICATION foo; - ^ +LINE 1: CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; + ^ -- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block BEGIN; -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); ERROR: CREATE SUBSCRIPTION ... WITH (create_slot = true) cannot run inside a transaction block COMMIT; -- fail - invalid connection string -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub; ERROR: invalid connection string syntax: missing "=" after "testconn" in connection info string -- fail - duplicate publications -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect= false); ERROR: publication name "foo" used more than once -- ok -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables -COMMENT ON SUBSCRIPTION testsub IS 'test subscription'; +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; obj_description ------------------- @@ -38,123 +38,123 @@ SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; (1 row) -- fail - name already exists -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); -ERROR: subscription "testsub" already exists +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); +ERROR: subscription "regress_testsub" already exists -- fail - must be superuser SET SESSION AUTHORIZATION 'regress_subscription_user2'; -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false); ERROR: must be superuser to create subscriptions SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - invalid option combinations -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,copy_data = true); ERROR: connect = false and copy_data = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,enabled = true); ERROR: connect = false and enabled = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,create_slot = true); ERROR: connect = false and create_slot = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,enabled = true); ERROR: slot_name = NONE and enabled = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot =true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,create_slot = true); ERROR: slot_name = NONE and create_slot = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); ERROR: subscription with slot_name = NONE must also set enabled = false -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,enabled = false); ERROR: subscription with slot_name = NONE must also set create_slot = false -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot =false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,create_slot = false); ERROR: subscription with slot_name = NONE must also set enabled = false -- ok - with slot_name = NONE -CREATE SUBSCRIPTION testsub3 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,connect = false); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables -- fail -ALTER SUBSCRIPTION testsub3 ENABLE; +ALTER SUBSCRIPTION regress_testsub3 ENABLE; ERROR: cannot enable subscription that does not have a slot name -ALTER SUBSCRIPTION testsub3 REFRESH PUBLICATION; +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; ERROR: ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions -DROP SUBSCRIPTION testsub3; +DROP SUBSCRIPTION regress_testsub3; -- fail - invalid connection string -ALTER SUBSCRIPTION testsub CONNECTION 'foobar'; +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; ERROR: invalid connection string syntax: missing "=" after "foobar" in connection info string \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo ----------+---------------------------+---------+-------------+--------------------+--------------------- - testsub | regress_subscription_user | f | {testpub} | off | dbname=doesnotexist + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +-----------------+---------------------------+---------+-------------+--------------------+----------------------------- + regress_testsub | regress_subscription_user | f | {testpub} | off | dbname=regress_doesnotexist (1 row) -ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); -ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (slot_name = 'newname'); +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); -- fail -ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2'; -ERROR: subscription "doesnotexist" does not exist -ALTER SUBSCRIPTION testsub SET (create_slot = false); +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; +ERROR: subscription "regress_doesnotexist" does not exist +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); ERROR: unrecognized subscription parameter: "create_slot" \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo ----------+---------------------------+---------+---------------------+--------------------+---------------------- - testsub | regress_subscription_user | f | {testpub2,testpub3} | off | dbname=doesnotexist2 + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +-----------------+---------------------------+---------+---------------------+--------------------+------------------------------ + regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | off | dbname=regress_doesnotexist2 (1 row) BEGIN; -ALTER SUBSCRIPTION testsub ENABLE; +ALTER SUBSCRIPTION regress_testsub ENABLE; \dRs - List of subscriptions - Name | Owner | Enabled | Publication ----------+---------------------------+---------+--------------------- - testsub | regress_subscription_user | t | {testpub2,testpub3} + List of subscriptions + Name | Owner | Enabled | Publication +-----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | t | {testpub2,testpub3} (1 row) -ALTER SUBSCRIPTION testsub DISABLE; +ALTER SUBSCRIPTION regress_testsub DISABLE; \dRs - List of subscriptions - Name | Owner | Enabled | Publication ----------+---------------------------+---------+--------------------- - testsub | regress_subscription_user | f | {testpub2,testpub3} + List of subscriptions + Name | Owner | Enabled | Publication +-----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | f | {testpub2,testpub3} (1 row) COMMIT; -- fail - must be owner of subscription SET ROLE regress_subscription_user_dummy; -ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy; -ERROR: must be owner of subscription testsub +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy; +ERROR: must be owner of subscription regress_testsub RESET ROLE; -ALTER SUBSCRIPTION testsub RENAME TO testsub_foo; -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local); -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar); +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo; +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar); ERROR: invalid value for parameter "synchronous_commit": "foobar" HINT: Available values: local, remote_write, remote_apply, on, off. \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo --------------+---------------------------+---------+---------------------+--------------------+---------------------- - testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | local | dbname=doesnotexist2 + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +---------------------+---------------------------+---------+---------------------+--------------------+------------------------------ + regress_testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | local | dbname=regress_doesnotexist2 (1 row) -- rename back to keep the rest simple -ALTER SUBSCRIPTION testsub_foo RENAME TO testsub; +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; -- fail - new owner must be superuser -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; -ERROR: permission denied to change owner of subscription "testsub" +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; +ERROR: permission denied to change owner of subscription "regress_testsub" HINT: The owner of a subscription must be a superuser. ALTER ROLE regress_subscription_user2 SUPERUSER; -- now it works -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; -- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; ERROR: DROP SUBSCRIPTION cannot run inside a transaction block COMMIT; -ALTER SUBSCRIPTION testsub SET (slot_name = NONE); +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); -- now it works BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -DROP SUBSCRIPTION IF EXISTS testsub; -NOTICE: subscription "testsub" does not exist, skipping -DROP SUBSCRIPTION testsub; -- fail -ERROR: subscription "testsub" does not exist +DROP SUBSCRIPTION IF EXISTS regress_testsub; +NOTICE: subscription "regress_testsub" does not exist, skipping +DROP SUBSCRIPTION regress_testsub; -- fail +ERROR: subscription "regress_testsub" does not exist RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user; DROP ROLE regress_subscription_user2; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index 1bfaf54..bd94cd6 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -46,7 +46,7 @@ CREATE TRANSFORM FOR int LANGUAGE SQL ( FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; -CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; -- test some error cases @@ -195,7 +195,7 @@ WITH objects (type, name, args) AS (VALUES ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), - ('subscription', '{addr_sub}', '{}'), + ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') ) SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, @@ -212,7 +212,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, --- DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub; +DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; diff --git a/src/test/regress/sql/rolenames.sql b/src/test/regress/sql/rolenames.sql index b285456..5a3cf44 100644 --- a/src/test/regress/sql/rolenames.sql +++ b/src/test/regress/sql/rolenames.sql @@ -40,12 +40,22 @@ SELECT r.rolname, s.srvname, m.umoptions ORDER BY 2; $$ LANGUAGE SQL; +-- +-- We test creation and use of these role names to ensure that the server +-- correctly distinguishes role keywords from quoted names that look like +-- those keywords. In a test environment, creation of these roles may +-- provoke warnings, so hide the warnings by raising client_min_messages. +-- +SET client_min_messages = ERROR; + CREATE ROLE "Public"; CREATE ROLE "None"; CREATE ROLE "current_user"; CREATE ROLE "session_user"; CREATE ROLE "user"; +RESET client_min_messages; + CREATE ROLE current_user; -- error CREATE ROLE current_role; -- error CREATE ROLE session_user; -- error diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index 36fa1bb..9e234ab 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -8,75 +8,75 @@ CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - no publications -CREATE SUBSCRIPTION testsub CONNECTION 'foo'; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; -- fail - no connection -CREATE SUBSCRIPTION testsub PUBLICATION foo; +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; -- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block BEGIN; -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); COMMIT; -- fail - invalid connection string -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub; -- fail - duplicate publications -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect= false); -- ok -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); -COMMENT ON SUBSCRIPTION testsub IS 'test subscription'; +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; -- fail - name already exists -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); -- fail - must be superuser SET SESSION AUTHORIZATION 'regress_subscription_user2'; -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false); SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - invalid option combinations -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot =true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot =false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,copy_data = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false,create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,enabled = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,create_slot = false); -- ok - with slot_name = NONE -CREATE SUBSCRIPTION testsub3 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE,connect = false); -- fail -ALTER SUBSCRIPTION testsub3 ENABLE; -ALTER SUBSCRIPTION testsub3 REFRESH PUBLICATION; +ALTER SUBSCRIPTION regress_testsub3 ENABLE; +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; -DROP SUBSCRIPTION testsub3; +DROP SUBSCRIPTION regress_testsub3; -- fail - invalid connection string -ALTER SUBSCRIPTION testsub CONNECTION 'foobar'; +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; \dRs+ -ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); -ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (slot_name = 'newname'); +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); -- fail -ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (create_slot = false); +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); \dRs+ BEGIN; -ALTER SUBSCRIPTION testsub ENABLE; +ALTER SUBSCRIPTION regress_testsub ENABLE; \dRs -ALTER SUBSCRIPTION testsub DISABLE; +ALTER SUBSCRIPTION regress_testsub DISABLE; \dRs @@ -84,38 +84,38 @@ COMMIT; -- fail - must be owner of subscription SET ROLE regress_subscription_user_dummy; -ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy; +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy; RESET ROLE; -ALTER SUBSCRIPTION testsub RENAME TO testsub_foo; -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local); -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar); +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo; +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar); \dRs+ -- rename back to keep the rest simple -ALTER SUBSCRIPTION testsub_foo RENAME TO testsub; +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; -- fail - new owner must be superuser -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; ALTER ROLE regress_subscription_user2 SUPERUSER; -- now it works -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; -- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -ALTER SUBSCRIPTION testsub SET (slot_name = NONE); +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); -- now it works BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -DROP SUBSCRIPTION IF EXISTS testsub; -DROP SUBSCRIPTION testsub; -- fail +DROP SUBSCRIPTION IF EXISTS regress_testsub; +DROP SUBSCRIPTION regress_testsub; -- fail RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user;
pgsql-hackers by date: