diff options
-rw-r--r-- | contrib/pg_overexplain/expected/pg_overexplain.out | 8 | ||||
-rw-r--r-- | contrib/pg_stat_statements/expected/level_tracking.out | 51 | ||||
-rw-r--r-- | contrib/pg_stat_statements/sql/level_tracking.sql | 26 | ||||
-rw-r--r-- | doc/src/sgml/ref/reindex.sgml | 7 | ||||
-rw-r--r-- | src/backend/parser/analyze.c | 17 | ||||
-rw-r--r-- | src/backend/storage/aio/aio.c | 113 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 21 | ||||
-rw-r--r-- | src/bin/pg_dump/t/002_pg_dump.pl | 6 | ||||
-rw-r--r-- | src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm | 1 |
9 files changed, 208 insertions, 42 deletions
diff --git a/contrib/pg_overexplain/expected/pg_overexplain.out b/contrib/pg_overexplain/expected/pg_overexplain.out index 44120c388af..cb5c396c519 100644 --- a/contrib/pg_overexplain/expected/pg_overexplain.out +++ b/contrib/pg_overexplain/expected/pg_overexplain.out @@ -119,7 +119,7 @@ $$); Subplans Needing Rewind: none Relation OIDs: NNN... Executor Parameter Types: none - Parse Location: 0 to end + Parse Location: 41 to end RTI 1 (relation, inherited, in-from-clause): Eref: vegetables (id, name, genus) Relation: vegetables @@ -240,7 +240,7 @@ $$); <Subplans-Needing-Rewind>none</Subplans-Needing-Rewind> + <Relation-OIDs>NNN...</Relation-OIDs> + <Executor-Parameter-Types>none</Executor-Parameter-Types> + - <Parse-Location>0 to end</Parse-Location> + + <Parse-Location>53 to end</Parse-Location> + </PlannedStmt> + <Range-Table> + <Range-Table-Entry> + @@ -344,7 +344,7 @@ $$); Subplans Needing Rewind: none Relation OIDs: NNN... Executor Parameter Types: none - Parse Location: 0 to end + Parse Location: 28 to end (37 rows) SET debug_parallel_query = false; @@ -372,7 +372,7 @@ $$); Subplans Needing Rewind: none Relation OIDs: NNN... Executor Parameter Types: 0 - Parse Location: 0 to end + Parse Location: 28 to end (15 rows) -- Create an index, and then attempt to force a nested loop with inner index diff --git a/contrib/pg_stat_statements/expected/level_tracking.out b/contrib/pg_stat_statements/expected/level_tracking.out index 03bea14d5da..75e785e1719 100644 --- a/contrib/pg_stat_statements/expected/level_tracking.out +++ b/contrib/pg_stat_statements/expected/level_tracking.out @@ -1319,6 +1319,57 @@ SELECT toplevel, calls, query FROM pg_stat_statements t | 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t (4 rows) +-- DO block --- multiple inner queries with separators +SET pg_stat_statements.track = 'all'; +SET pg_stat_statements.track_utility = TRUE; +CREATE TABLE pgss_do_util_tab_1 (a int); +CREATE TABLE pgss_do_util_tab_2 (a int); +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + t +--- + t +(1 row) + +DO $$ +DECLARE BEGIN + EXECUTE 'CREATE TABLE pgss_do_table (id INT); DROP TABLE pgss_do_table'; + EXECUTE 'SELECT a FROM pgss_do_util_tab_1; SELECT a FROM pgss_do_util_tab_2'; +END $$; +SELECT toplevel, calls, rows, query FROM pg_stat_statements + WHERE toplevel IS FALSE + ORDER BY query COLLATE "C"; + toplevel | calls | rows | query +----------+-------+------+------------------------------------- + f | 1 | 0 | CREATE TABLE pgss_do_table (id INT) + f | 1 | 0 | DROP TABLE pgss_do_table + f | 1 | 0 | SELECT a FROM pgss_do_util_tab_1 + f | 1 | 0 | SELECT a FROM pgss_do_util_tab_2 +(4 rows) + +SELECT pg_stat_statements_reset() IS NOT NULL AS t; + t +--- + t +(1 row) + +-- Note the extra semicolon at the end of the query. +DO $$ +DECLARE BEGIN + EXECUTE 'CREATE TABLE pgss_do_table (id INT); DROP TABLE pgss_do_table;'; + EXECUTE 'SELECT a FROM pgss_do_util_tab_1; SELECT a FROM pgss_do_util_tab_2;'; +END $$; +SELECT toplevel, calls, rows, query FROM pg_stat_statements + WHERE toplevel IS FALSE + ORDER BY query COLLATE "C"; + toplevel | calls | rows | query +----------+-------+------+------------------------------------- + f | 1 | 0 | CREATE TABLE pgss_do_table (id INT) + f | 1 | 0 | DROP TABLE pgss_do_table + f | 1 | 0 | SELECT a FROM pgss_do_util_tab_1 + f | 1 | 0 | SELECT a FROM pgss_do_util_tab_2 +(4 rows) + +DROP TABLE pgss_do_util_tab_1, pgss_do_util_tab_2; -- PL/pgSQL function - top-level tracking. SET pg_stat_statements.track = 'top'; SET pg_stat_statements.track_utility = FALSE; diff --git a/contrib/pg_stat_statements/sql/level_tracking.sql b/contrib/pg_stat_statements/sql/level_tracking.sql index 6b81230f186..86f007e8552 100644 --- a/contrib/pg_stat_statements/sql/level_tracking.sql +++ b/contrib/pg_stat_statements/sql/level_tracking.sql @@ -334,6 +334,32 @@ END; $$; SELECT toplevel, calls, query FROM pg_stat_statements ORDER BY query COLLATE "C", toplevel; +-- DO block --- multiple inner queries with separators +SET pg_stat_statements.track = 'all'; +SET pg_stat_statements.track_utility = TRUE; +CREATE TABLE pgss_do_util_tab_1 (a int); +CREATE TABLE pgss_do_util_tab_2 (a int); +SELECT pg_stat_statements_reset() IS NOT NULL AS t; +DO $$ +DECLARE BEGIN + EXECUTE 'CREATE TABLE pgss_do_table (id INT); DROP TABLE pgss_do_table'; + EXECUTE 'SELECT a FROM pgss_do_util_tab_1; SELECT a FROM pgss_do_util_tab_2'; +END $$; +SELECT toplevel, calls, rows, query FROM pg_stat_statements + WHERE toplevel IS FALSE + ORDER BY query COLLATE "C"; +SELECT pg_stat_statements_reset() IS NOT NULL AS t; +-- Note the extra semicolon at the end of the query. +DO $$ +DECLARE BEGIN + EXECUTE 'CREATE TABLE pgss_do_table (id INT); DROP TABLE pgss_do_table;'; + EXECUTE 'SELECT a FROM pgss_do_util_tab_1; SELECT a FROM pgss_do_util_tab_2;'; +END $$; +SELECT toplevel, calls, rows, query FROM pg_stat_statements + WHERE toplevel IS FALSE + ORDER BY query COLLATE "C"; +DROP TABLE pgss_do_util_tab_1, pgss_do_util_tab_2; + -- PL/pgSQL function - top-level tracking. SET pg_stat_statements.track = 'top'; SET pg_stat_statements.track_utility = FALSE; diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 5b3c769800e..c4055397146 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -465,14 +465,17 @@ Indexes: </programlisting> If the index marked <literal>INVALID</literal> is suffixed - <literal>ccnew</literal>, then it corresponds to the transient + <literal>_ccnew</literal>, then it corresponds to the transient index created during the concurrent operation, and the recommended recovery method is to drop it using <literal>DROP INDEX</literal>, then attempt <command>REINDEX CONCURRENTLY</command> again. - If the invalid index is instead suffixed <literal>ccold</literal>, + If the invalid index is instead suffixed <literal>_ccold</literal>, it corresponds to the original index which could not be dropped; the recommended recovery method is to just drop said index, since the rebuild proper has been successful. + A nonzero number may be appended to the suffix of the invalid index + names to keep them unique, like <literal>_ccnew1</literal>, + <literal>_ccold2</literal>, etc. </para> <para> diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 1f4d6adda52..a16fdd65601 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -253,20 +253,14 @@ parse_sub_analyze(Node *parseTree, ParseState *parentParseState, * statements. However, we have the statement's location plus the length * (p_stmt_len) and location (p_stmt_location) of the top level RawStmt, * stored in pstate. Thus, the statement's length is the RawStmt's length - * minus how much we've advanced in the RawStmt's string. + * minus how much we've advanced in the RawStmt's string. If p_stmt_len + * is 0, the SQL string is used up to its end. */ static void setQueryLocationAndLength(ParseState *pstate, Query *qry, Node *parseTree) { ParseLoc stmt_len = 0; - /* - * If there is no information about the top RawStmt's length, leave it at - * 0 to use the whole string. - */ - if (pstate->p_stmt_len == 0) - return; - switch (nodeTag(parseTree)) { case T_InsertStmt: @@ -308,11 +302,12 @@ setQueryLocationAndLength(ParseState *pstate, Query *qry, Node *parseTree) /* Statement's length is known, use it */ qry->stmt_len = stmt_len; } - else + else if (pstate->p_stmt_len > 0) { /* - * Compute the statement's length from the statement's location and - * the RawStmt's length and location. + * The top RawStmt's length is known, so calculate the statement's + * length from the statement's location and the RawStmt's length and + * location. */ qry->stmt_len = pstate->p_stmt_len - (qry->stmt_location - pstate->p_stmt_location); } diff --git a/src/backend/storage/aio/aio.c b/src/backend/storage/aio/aio.c index ebb5a771bfd..c64d815ebd1 100644 --- a/src/backend/storage/aio/aio.c +++ b/src/backend/storage/aio/aio.c @@ -184,6 +184,8 @@ pgaio_io_acquire(struct ResourceOwnerData *resowner, PgAioReturn *ret) PgAioHandle * pgaio_io_acquire_nb(struct ResourceOwnerData *resowner, PgAioReturn *ret) { + PgAioHandle *ioh = NULL; + if (pgaio_my_backend->num_staged_ios >= PGAIO_SUBMIT_BATCH_SIZE) { Assert(pgaio_my_backend->num_staged_ios == PGAIO_SUBMIT_BATCH_SIZE); @@ -193,10 +195,17 @@ pgaio_io_acquire_nb(struct ResourceOwnerData *resowner, PgAioReturn *ret) if (pgaio_my_backend->handed_out_io) elog(ERROR, "API violation: Only one IO can be handed out"); + /* + * Probably not needed today, as interrupts should not process this IO, + * but... + */ + HOLD_INTERRUPTS(); + if (!dclist_is_empty(&pgaio_my_backend->idle_ios)) { dlist_node *ion = dclist_pop_head_node(&pgaio_my_backend->idle_ios); - PgAioHandle *ioh = dclist_container(PgAioHandle, node, ion); + + ioh = dclist_container(PgAioHandle, node, ion); Assert(ioh->state == PGAIO_HS_IDLE); Assert(ioh->owner_procno == MyProcNumber); @@ -212,11 +221,11 @@ pgaio_io_acquire_nb(struct ResourceOwnerData *resowner, PgAioReturn *ret) ioh->report_return = ret; ret->result.status = PGAIO_RS_UNKNOWN; } - - return ioh; } - return NULL; + RESUME_INTERRUPTS(); + + return ioh; } /* @@ -233,6 +242,12 @@ pgaio_io_release(PgAioHandle *ioh) Assert(ioh->resowner); pgaio_my_backend->handed_out_io = NULL; + + /* + * Note that no interrupts are processed between the handed_out_io + * check and the call to reclaim - that's important as otherwise an + * interrupt could have already reclaimed the handle. + */ pgaio_io_reclaim(ioh); } else @@ -251,6 +266,12 @@ pgaio_io_release_resowner(dlist_node *ioh_node, bool on_error) Assert(ioh->resowner); + /* + * Otherwise an interrupt, in the middle of releasing the IO, could end up + * trying to wait for the IO, leading to state confusion. + */ + HOLD_INTERRUPTS(); + ResourceOwnerForgetAioHandle(ioh->resowner, &ioh->resowner_node); ioh->resowner = NULL; @@ -291,6 +312,8 @@ pgaio_io_release_resowner(dlist_node *ioh_node, bool on_error) */ if (ioh->report_return) ioh->report_return = NULL; + + RESUME_INTERRUPTS(); } /* @@ -359,6 +382,13 @@ pgaio_io_get_wref(PgAioHandle *ioh, PgAioWaitRef *iow) static inline void pgaio_io_update_state(PgAioHandle *ioh, PgAioHandleState new_state) { + /* + * All callers need to have held interrupts in some form, otherwise + * interrupt processing could wait for the IO to complete, while in an + * intermediary state. + */ + Assert(!INTERRUPTS_CAN_BE_PROCESSED()); + pgaio_debug_io(DEBUG5, ioh, "updating state to %s", pgaio_io_state_get_name(new_state)); @@ -396,6 +426,13 @@ pgaio_io_stage(PgAioHandle *ioh, PgAioOp op) Assert(pgaio_my_backend->handed_out_io == ioh); Assert(pgaio_io_has_target(ioh)); + /* + * Otherwise an interrupt, in the middle of staging and possibly executing + * the IO, could end up trying to wait for the IO, leading to state + * confusion. + */ + HOLD_INTERRUPTS(); + ioh->op = op; ioh->result = 0; @@ -435,6 +472,8 @@ pgaio_io_stage(PgAioHandle *ioh, PgAioOp op) pgaio_io_prepare_submit(ioh); pgaio_io_perform_synchronously(ioh); } + + RESUME_INTERRUPTS(); } bool @@ -544,8 +583,8 @@ pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation) && state != PGAIO_HS_COMPLETED_SHARED && state != PGAIO_HS_COMPLETED_LOCAL) { - elog(PANIC, "waiting for own IO in wrong state: %d", - state); + elog(PANIC, "waiting for own IO %d in wrong state: %s", + pgaio_io_get_id(ioh), pgaio_io_get_state_name(ioh)); } } @@ -599,7 +638,13 @@ pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation) case PGAIO_HS_COMPLETED_SHARED: case PGAIO_HS_COMPLETED_LOCAL: - /* see above */ + + /* + * Note that no interrupts are processed between + * pgaio_io_was_recycled() and this check - that's important + * as otherwise an interrupt could have already reclaimed the + * handle. + */ if (am_owner) pgaio_io_reclaim(ioh); return; @@ -610,6 +655,11 @@ pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation) /* * Make IO handle ready to be reused after IO has completed or after the * handle has been released without being used. + * + * Note that callers need to be careful about only calling this in the right + * state and that no interrupts can be processed between the state check and + * the call to pgaio_io_reclaim(). Otherwise interrupt processing could + * already have reclaimed the handle. */ static void pgaio_io_reclaim(PgAioHandle *ioh) @@ -618,6 +668,9 @@ pgaio_io_reclaim(PgAioHandle *ioh) Assert(ioh->owner_procno == MyProcNumber); Assert(ioh->state != PGAIO_HS_IDLE); + /* see comment in function header */ + HOLD_INTERRUPTS(); + /* * It's a bit ugly, but right now the easiest place to put the execution * of local completion callbacks is this function, as we need to execute @@ -685,6 +738,8 @@ pgaio_io_reclaim(PgAioHandle *ioh) * efficient in cases where only a few IOs are used. */ dclist_push_head(&pgaio_my_backend->idle_ios, &ioh->node); + + RESUME_INTERRUPTS(); } /* @@ -700,7 +755,7 @@ pgaio_io_wait_for_free(void) pgaio_debug(DEBUG2, "waiting for free IO with %d pending, %d in-flight, %d idle IOs", pgaio_my_backend->num_staged_ios, dclist_count(&pgaio_my_backend->in_flight_ios), - dclist_is_empty(&pgaio_my_backend->idle_ios)); + dclist_count(&pgaio_my_backend->idle_ios)); /* * First check if any of our IOs actually have completed - when using @@ -714,6 +769,11 @@ pgaio_io_wait_for_free(void) if (ioh->state == PGAIO_HS_COMPLETED_SHARED) { + /* + * Note that no interrupts are processed between the state check + * and the call to reclaim - that's important as otherwise an + * interrupt could have already reclaimed the handle. + */ pgaio_io_reclaim(ioh); reclaimed++; } @@ -730,13 +790,17 @@ pgaio_io_wait_for_free(void) if (pgaio_my_backend->num_staged_ios > 0) pgaio_submit_staged(); + /* possibly some IOs finished during submission */ + if (!dclist_is_empty(&pgaio_my_backend->idle_ios)) + return; + if (dclist_count(&pgaio_my_backend->in_flight_ios) == 0) ereport(ERROR, errmsg_internal("no free IOs despite no in-flight IOs"), errdetail_internal("%d pending, %d in-flight, %d idle IOs", pgaio_my_backend->num_staged_ios, dclist_count(&pgaio_my_backend->in_flight_ios), - dclist_is_empty(&pgaio_my_backend->idle_ios))); + dclist_count(&pgaio_my_backend->idle_ios))); /* * Wait for the oldest in-flight IO to complete. @@ -747,6 +811,7 @@ pgaio_io_wait_for_free(void) { PgAioHandle *ioh = dclist_head_element(PgAioHandle, node, &pgaio_my_backend->in_flight_ios); + uint64 generation = ioh->generation; switch (ioh->state) { @@ -770,13 +835,24 @@ pgaio_io_wait_for_free(void) * In a more general case this would be racy, because the * generation could increase after we read ioh->state above. * But we are only looking at IOs by the current backend and - * the IO can only be recycled by this backend. + * the IO can only be recycled by this backend. Even this is + * only OK because we get the handle's generation before + * potentially processing interrupts, e.g. as part of + * pgaio_debug_io(). */ - pgaio_io_wait(ioh, ioh->generation); + pgaio_io_wait(ioh, generation); break; case PGAIO_HS_COMPLETED_SHARED: - /* it's possible that another backend just finished this IO */ + + /* + * It's possible that another backend just finished this IO. + * + * Note that no interrupts are processed between the state + * check and the call to reclaim - that's important as + * otherwise an interrupt could have already reclaimed the + * handle. + */ pgaio_io_reclaim(ioh); break; } @@ -926,6 +1002,11 @@ pgaio_wref_check_done(PgAioWaitRef *iow) if (state == PGAIO_HS_COMPLETED_SHARED || state == PGAIO_HS_COMPLETED_LOCAL) { + /* + * Note that no interrupts are processed between + * pgaio_io_was_recycled() and this check - that's important as + * otherwise an interrupt could have already reclaimed the handle. + */ if (am_owner) pgaio_io_reclaim(ioh); return true; @@ -1153,11 +1234,14 @@ pgaio_closing_fd(int fd) { dlist_iter iter; PgAioHandle *ioh = NULL; + uint64 generation; dclist_foreach(iter, &pgaio_my_backend->in_flight_ios) { ioh = dclist_container(PgAioHandle, node, iter.cur); + generation = ioh->generation; + if (pgaio_io_uses_fd(ioh, fd)) break; else @@ -1172,7 +1256,7 @@ pgaio_closing_fd(int fd) fd, dclist_count(&pgaio_my_backend->in_flight_ios)); /* see comment in pgaio_io_wait_for_free() about raciness */ - pgaio_io_wait(ioh, ioh->generation); + pgaio_io_wait(ioh, generation); } } } @@ -1201,13 +1285,14 @@ pgaio_shutdown(int code, Datum arg) while (!dclist_is_empty(&pgaio_my_backend->in_flight_ios)) { PgAioHandle *ioh = dclist_head_element(PgAioHandle, node, &pgaio_my_backend->in_flight_ios); + uint64 generation = ioh->generation; pgaio_debug_io(DEBUG2, ioh, "waiting for IO to complete during shutdown, %d in-flight IOs", dclist_count(&pgaio_my_backend->in_flight_ios)); /* see comment in pgaio_io_wait_for_free() about raciness */ - pgaio_io_wait(ioh, ioh->generation); + pgaio_io_wait(ioh, generation); } pgaio_my_backend = NULL; diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index e2e7975b34e..c73e73a87d1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -10765,6 +10765,9 @@ fetchAttributeStats(Archive *fout) restarted = true; } + appendPQExpBufferChar(nspnames, '{'); + appendPQExpBufferChar(relnames, '{'); + /* * Scan the TOC for the next set of relevant stats entries. We assume * that statistics are dumped in the order they are listed in the TOC. @@ -10776,23 +10779,25 @@ fetchAttributeStats(Archive *fout) if ((te->reqs & REQ_STATS) != 0 && strcmp(te->desc, "STATISTICS DATA") == 0) { - appendPQExpBuffer(nspnames, "%s%s", count ? "," : "", - fmtId(te->namespace)); - appendPQExpBuffer(relnames, "%s%s", count ? "," : "", - fmtId(te->tag)); + appendPGArray(nspnames, te->namespace); + appendPGArray(relnames, te->tag); count++; } } + appendPQExpBufferChar(nspnames, '}'); + appendPQExpBufferChar(relnames, '}'); + /* Execute the query for the next batch of relations. */ if (count > 0) { PQExpBuffer query = createPQExpBuffer(); - appendPQExpBuffer(query, "EXECUTE getAttributeStats(" - "'{%s}'::pg_catalog.name[]," - "'{%s}'::pg_catalog.name[])", - nspnames->data, relnames->data); + appendPQExpBufferStr(query, "EXECUTE getAttributeStats("); + appendStringLiteralAH(query, nspnames->data, fout); + appendPQExpBufferStr(query, "::pg_catalog.name[],"); + appendStringLiteralAH(query, relnames->data, fout); + appendPQExpBufferStr(query, "::pg_catalog.name[])"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); destroyPQExpBuffer(query); } diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 55d892d9c16..cf34f71ea11 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -4834,13 +4834,13 @@ my %tests = ( CREATE TABLE dump_test.has_stats AS SELECT g.g AS x, g.g / 2 AS y FROM generate_series(1,100) AS g(g); CREATE MATERIALIZED VIEW dump_test.has_stats_mv AS SELECT * FROM dump_test.has_stats; - CREATE INDEX dup_test_post_data_ix ON dump_test.has_stats(x, (x - 1)); + CREATE INDEX """dump_test""\'s post-data index" ON dump_test.has_stats(x, (x - 1)); ANALYZE dump_test.has_stats, dump_test.has_stats_mv;', regexp => qr/^ \QSELECT * FROM pg_catalog.pg_restore_relation_stats(\E\s+ 'version',\s'\d+'::integer,\s+ 'schemaname',\s'dump_test',\s+ - 'relname',\s'dup_test_post_data_ix',\s+ + 'relname',\s'"dump_test"''s\ post-data\ index',\s+ 'relpages',\s'\d+'::integer,\s+ 'reltuples',\s'\d+'::real,\s+ 'relallvisible',\s'\d+'::integer,\s+ @@ -4849,7 +4849,7 @@ my %tests = ( \QSELECT * FROM pg_catalog.pg_restore_attribute_stats(\E\s+ 'version',\s'\d+'::integer,\s+ 'schemaname',\s'dump_test',\s+ - 'relname',\s'dup_test_post_data_ix',\s+ + 'relname',\s'"dump_test"''s\ post-data\ index',\s+ 'attnum',\s'2'::smallint,\s+ 'inherited',\s'f'::boolean,\s+ 'null_frac',\s'0'::real,\s+ diff --git a/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm b/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm index 609275e2c26..1725fe2f948 100644 --- a/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm +++ b/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm @@ -538,6 +538,7 @@ my @_unused_view_qualifiers = ( { obj => 'VIEW public.limit_thousand_v_2', qual => 'onek' }, { obj => 'VIEW public.limit_thousand_v_3', qual => 'onek' }, { obj => 'VIEW public.limit_thousand_v_4', qual => 'onek' }, + { obj => 'VIEW public.limit_thousand_v_5', qual => 'onek' }, # Since 14 { obj => 'MATERIALIZED VIEW public.compressmv', qual => 'cmdata1' }); |