2021-05-07 16:56:14 +02:00
|
|
|
|
2023-01-02 21:00:37 +01:00
|
|
|
# Copyright (c) 2021-2023, PostgreSQL Global Development Group
|
2021-05-07 16:56:14 +02:00
|
|
|
|
2014-04-15 03:33:46 +02:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
use PostgreSQL::Test::Cluster;
|
|
|
|
use PostgreSQL::Test::Utils;
|
2022-02-11 20:54:44 +01:00
|
|
|
use Test::More;
|
2014-04-15 03:33:46 +02:00
|
|
|
|
|
|
|
program_help_ok('reindexdb');
|
|
|
|
program_version_ok('reindexdb');
|
|
|
|
program_options_handling_ok('reindexdb');
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $node = PostgreSQL::Test::Cluster->new('main');
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$node->init;
|
|
|
|
$node->start;
|
2014-04-15 03:33:46 +02:00
|
|
|
|
|
|
|
$ENV{PGOPTIONS} = '--client-min-messages=WARNING';
|
|
|
|
|
2021-03-03 02:14:21 +01:00
|
|
|
# Create a tablespace for testing.
|
|
|
|
my $tbspace_path = $node->basedir . '/regress_reindex_tbspace';
|
|
|
|
mkdir $tbspace_path or die "cannot create directory $tbspace_path";
|
|
|
|
my $tbspace_name = 'reindex_tbspace';
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE TABLESPACE $tbspace_name LOCATION '$tbspace_path';");
|
|
|
|
|
|
|
|
# Use text as data type to get a toast table.
|
2016-03-03 21:58:30 +01:00
|
|
|
$node->safe_psql('postgres',
|
2021-03-03 02:14:21 +01:00
|
|
|
'CREATE TABLE test1 (a text); CREATE INDEX test1x ON test1 (a);');
|
|
|
|
# Collect toast table and index names of this relation, for later use.
|
|
|
|
my $toast_table = $node->safe_psql('postgres',
|
|
|
|
"SELECT reltoastrelid::regclass FROM pg_class WHERE oid = 'test1'::regclass;"
|
|
|
|
);
|
|
|
|
my $toast_index = $node->safe_psql('postgres',
|
|
|
|
"SELECT indexrelid::regclass FROM pg_index WHERE indrelid = '$toast_table'::regclass;"
|
|
|
|
);
|
|
|
|
|
2022-07-19 03:51:27 +02:00
|
|
|
# Set of SQL queries to cross-check the state of relfilenodes across
|
|
|
|
# REINDEX operations. A set of relfilenodes is saved from the catalogs
|
|
|
|
# and then compared with pg_class.
|
|
|
|
$node->safe_psql('postgres',
|
2022-09-28 15:45:27 +02:00
|
|
|
'CREATE TABLE index_relfilenodes (parent regclass, indname text, indoid oid, relfilenode oid);'
|
2022-07-19 03:51:27 +02:00
|
|
|
);
|
|
|
|
# Save the relfilenode of a set of toast indexes, one from the catalog
|
|
|
|
# pg_constraint and one from the test table.
|
|
|
|
my $fetch_toast_relfilenodes =
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
qq{SELECT b.oid::regclass, c.oid::regclass::text, c.oid, c.relfilenode
|
2022-07-19 03:51:27 +02:00
|
|
|
FROM pg_class a
|
|
|
|
JOIN pg_class b ON (a.oid = b.reltoastrelid)
|
|
|
|
JOIN pg_index i on (a.oid = i.indrelid)
|
|
|
|
JOIN pg_class c on (i.indexrelid = c.oid)
|
|
|
|
WHERE b.oid IN ('pg_constraint'::regclass, 'test1'::regclass)};
|
|
|
|
# Same for relfilenodes of normal indexes. This saves the relfilenode
|
|
|
|
# from an index of pg_constraint, and from the index of the test table.
|
2023-05-19 23:24:48 +02:00
|
|
|
my $fetch_index_relfilenodes =
|
|
|
|
qq{SELECT i.indrelid, a.oid::regclass::text, a.oid, a.relfilenode
|
2022-07-19 03:51:27 +02:00
|
|
|
FROM pg_class a
|
|
|
|
JOIN pg_index i ON (i.indexrelid = a.oid)
|
|
|
|
WHERE a.relname IN ('pg_constraint_oid_index', 'test1x')};
|
|
|
|
my $save_relfilenodes =
|
2022-07-21 04:00:48 +02:00
|
|
|
"INSERT INTO index_relfilenodes $fetch_toast_relfilenodes;"
|
|
|
|
. "INSERT INTO index_relfilenodes $fetch_index_relfilenodes;";
|
2022-07-19 03:51:27 +02:00
|
|
|
|
|
|
|
# Query to compare a set of relfilenodes saved with the contents of pg_class.
|
|
|
|
# Note that this does not join using OIDs, as CONCURRENTLY would change them
|
|
|
|
# when reindexing. A filter is applied on the toast index names, even if this
|
|
|
|
# does not make a difference between the catalog and normal ones. The ordering
|
|
|
|
# based on the name is enough to ensure a fixed output, where the name of the
|
|
|
|
# parent table is included to provide more context.
|
|
|
|
my $compare_relfilenodes = qq(SELECT b.parent::regclass,
|
2022-07-21 04:00:48 +02:00
|
|
|
regexp_replace(b.indname::text, '(pg_toast.pg_toast_)\\d+(_index)', '\\1<oid>\\2'),
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
CASE WHEN a.oid = b.indoid THEN 'OID is unchanged'
|
|
|
|
ELSE 'OID has changed' END,
|
2022-07-19 03:51:27 +02:00
|
|
|
CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged'
|
|
|
|
ELSE 'relfilenode has changed' END
|
2022-07-21 04:00:48 +02:00
|
|
|
FROM index_relfilenodes b
|
2022-07-19 03:51:27 +02:00
|
|
|
JOIN pg_class a ON b.indname::text = a.oid::regclass::text
|
|
|
|
ORDER BY b.parent::text, b.indname::text);
|
|
|
|
|
|
|
|
# Save the set of relfilenodes and compare them.
|
|
|
|
$node->safe_psql('postgres', $save_relfilenodes);
|
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', 'postgres' ],
|
|
|
|
qr/statement: REINDEX DATABASE postgres;/,
|
|
|
|
'SQL REINDEX run');
|
|
|
|
my $relnode_info = $node->safe_psql('postgres', $compare_relfilenodes);
|
|
|
|
is( $relnode_info,
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
qq(pg_constraint|pg_constraint_oid_index|OID is unchanged|relfilenode is unchanged
|
|
|
|
pg_constraint|pg_toast.pg_toast_<oid>_index|OID is unchanged|relfilenode is unchanged
|
|
|
|
test1|pg_toast.pg_toast_<oid>_index|OID is unchanged|relfilenode has changed
|
|
|
|
test1|test1x|OID is unchanged|relfilenode has changed),
|
2022-07-19 03:51:27 +02:00
|
|
|
'relfilenode change after REINDEX DATABASE');
|
|
|
|
|
|
|
|
# Re-save and run the second one.
|
|
|
|
$node->safe_psql('postgres',
|
2022-07-21 04:00:48 +02:00
|
|
|
"TRUNCATE index_relfilenodes; $save_relfilenodes");
|
2022-07-19 03:51:27 +02:00
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '-s', 'postgres' ],
|
|
|
|
qr/statement: REINDEX SYSTEM postgres;/,
|
|
|
|
'reindex system tables');
|
|
|
|
$relnode_info = $node->safe_psql('postgres', $compare_relfilenodes);
|
|
|
|
is( $relnode_info,
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
qq(pg_constraint|pg_constraint_oid_index|OID is unchanged|relfilenode has changed
|
|
|
|
pg_constraint|pg_toast.pg_toast_<oid>_index|OID is unchanged|relfilenode has changed
|
|
|
|
test1|pg_toast.pg_toast_<oid>_index|OID is unchanged|relfilenode is unchanged
|
|
|
|
test1|test1x|OID is unchanged|relfilenode is unchanged),
|
2022-07-19 03:51:27 +02:00
|
|
|
'relfilenode change after REINDEX SYSTEM');
|
|
|
|
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$node->issues_sql_like(
|
2015-04-04 19:34:23 +02:00
|
|
|
[ 'reindexdb', '-t', 'test1', 'postgres' ],
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
qr/statement: REINDEX TABLE public\.test1;/,
|
2014-04-15 03:33:46 +02:00
|
|
|
'reindex specific table');
|
2021-03-03 02:14:21 +01:00
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '-t', 'test1', '--tablespace', $tbspace_name, 'postgres' ],
|
|
|
|
qr/statement: REINDEX \(TABLESPACE $tbspace_name\) TABLE public\.test1;/,
|
|
|
|
'reindex specific table on tablespace');
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$node->issues_sql_like(
|
2015-04-04 19:34:23 +02:00
|
|
|
[ 'reindexdb', '-i', 'test1x', 'postgres' ],
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
qr/statement: REINDEX INDEX public\.test1x;/,
|
2014-04-15 03:33:46 +02:00
|
|
|
'reindex specific index');
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$node->issues_sql_like(
|
2015-04-04 19:34:23 +02:00
|
|
|
[ 'reindexdb', '-S', 'pg_catalog', 'postgres' ],
|
2014-12-08 16:28:00 +01:00
|
|
|
qr/statement: REINDEX SCHEMA pg_catalog;/,
|
|
|
|
'reindex specific schema');
|
Refactor Perl test code
The original code was a bit clunky; make it more amenable for further
reuse by creating a new Perl package PostgresNode, which is an
object-oriented representation of a single server, with some support
routines such as init, start, stop, psql. This serves as a better basis
on which to build further test code, and enables writing tests that use
more than one server without too much complication.
This commit modifies a lot of the existing test files, mostly to remove
explicit calls to system commands (pg_ctl) replacing them with method
calls of a PostgresNode object. The result is quite a bit more
straightforward.
Also move some initialization code to BEGIN and INIT blocks instead of
having it straight in as top-level code.
This commit also introduces package RecursiveCopy so that we can copy
whole directories without having to depend on packages that may not be
present on vanilla Perl 5.8 installations.
I also ran perltidy on the modified files, which changes some code sites
that are not otherwise touched by this patch. I tried to avoid this,
but it ended up being more trouble than it's worth.
Authors: Michael Paquier, Álvaro Herrera
Review: Noah Misch
2015-12-02 22:46:16 +01:00
|
|
|
$node->issues_sql_like(
|
2015-05-15 14:45:55 +02:00
|
|
|
[ 'reindexdb', '-v', '-t', 'test1', 'postgres' ],
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
qr/statement: REINDEX \(VERBOSE\) TABLE public\.test1;/,
|
2015-05-15 14:45:55 +02:00
|
|
|
'reindex with verbose output');
|
2021-03-03 02:14:21 +01:00
|
|
|
$node->issues_sql_like(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '-v', '-t', 'test1',
|
2021-03-03 02:14:21 +01:00
|
|
|
'--tablespace', $tbspace_name, 'postgres'
|
|
|
|
],
|
|
|
|
qr/statement: REINDEX \(VERBOSE, TABLESPACE $tbspace_name\) TABLE public\.test1;/,
|
|
|
|
'reindex with verbose output and tablespace');
|
2016-08-04 20:44:23 +02:00
|
|
|
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
# Same with --concurrently.
|
|
|
|
# Save the state of the relations and compare them after the DATABASE
|
|
|
|
# rebuild.
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"TRUNCATE index_relfilenodes; $save_relfilenodes");
|
2019-03-29 08:25:20 +01:00
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '--concurrently', 'postgres' ],
|
|
|
|
qr/statement: REINDEX DATABASE CONCURRENTLY postgres;/,
|
|
|
|
'SQL REINDEX CONCURRENTLY run');
|
Fix a few issues with REINDEX grammar
This addresses a couple of bugs in the REINDEX grammar, introduced by
83011ce:
- A name was never specified for DATABASE/SYSTEM, even if the query
included one. This caused such REINDEX queries to always work with any
object name, but we should complain if the object name specified does
not match the name of the database we are connected to. A test is added
for this case in the main regression test suite, provided by Álvaro.
- REINDEX SYSTEM CONCURRENTLY [name] was getting rejected in the
parser. Concurrent rebuilds are not supported for catalogs but the
error provided at execution time is more helpful for the user, and
allowing this flavor results in a simplification of the parsing logic.
- REINDEX DATABASE CONCURRENTLY was rebuilding the index in a
non-concurrent way, as the option was not being appended correctly in
the list of DefElems in ReindexStmt (REINDEX (CONCURRENTLY) DATABASE was
working fine. A test is added in the TAP tests of reindexdb for this
case, where we already have a REINDEX DATABASE CONCURRENTLY query
running on a small-ish instance. This relies on the work done in
2cbc3c1 for SYSTEM, but here we check if the OIDs of the index relations
match or not after the concurrent rebuild. Note that in order to get
this part to work, I had to tweak the tests so as the index OID and
names are saved separately. This change not affect the reliability or
of the coverage of the existing tests.
While on it, I have implemented a tweak in the grammar to reduce the
parsing by one branch, simplifying things even more.
Author: Michael Paquier, Álvaro Herrera
Discussion: https://postgr.es/m/YttqI6O64wDxGn0K@paquier.xyz
2022-07-26 03:16:26 +02:00
|
|
|
$relnode_info = $node->safe_psql('postgres', $compare_relfilenodes);
|
|
|
|
is( $relnode_info,
|
|
|
|
qq(pg_constraint|pg_constraint_oid_index|OID is unchanged|relfilenode is unchanged
|
|
|
|
pg_constraint|pg_toast.pg_toast_<oid>_index|OID is unchanged|relfilenode is unchanged
|
|
|
|
test1|pg_toast.pg_toast_<oid>_index|OID has changed|relfilenode has changed
|
|
|
|
test1|test1x|OID has changed|relfilenode has changed),
|
|
|
|
'OID change after REINDEX DATABASE CONCURRENTLY');
|
2019-03-29 08:25:20 +01:00
|
|
|
|
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '--concurrently', '-t', 'test1', 'postgres' ],
|
|
|
|
qr/statement: REINDEX TABLE CONCURRENTLY public\.test1;/,
|
|
|
|
'reindex specific table concurrently');
|
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '--concurrently', '-i', 'test1x', 'postgres' ],
|
|
|
|
qr/statement: REINDEX INDEX CONCURRENTLY public\.test1x;/,
|
|
|
|
'reindex specific index concurrently');
|
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '--concurrently', '-S', 'public', 'postgres' ],
|
|
|
|
qr/statement: REINDEX SCHEMA CONCURRENTLY public;/,
|
|
|
|
'reindex specific schema concurrently');
|
|
|
|
$node->command_fails([ 'reindexdb', '--concurrently', '-s', 'postgres' ],
|
|
|
|
'reindex system tables concurrently');
|
|
|
|
$node->issues_sql_like(
|
2021-03-02 05:18:06 +01:00
|
|
|
[ 'reindexdb', '--concurrently', '-v', '-t', 'test1', 'postgres' ],
|
|
|
|
qr/statement: REINDEX \(VERBOSE\) TABLE CONCURRENTLY public\.test1;/,
|
|
|
|
'reindex with verbose output concurrently');
|
2021-03-03 02:14:21 +01:00
|
|
|
$node->issues_sql_like(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '--concurrently', '-v', '-t',
|
|
|
|
'test1', '--tablespace', $tbspace_name, 'postgres'
|
2021-03-03 02:14:21 +01:00
|
|
|
],
|
|
|
|
qr/statement: REINDEX \(VERBOSE, TABLESPACE $tbspace_name\) TABLE CONCURRENTLY public\.test1;/,
|
|
|
|
'reindex concurrently with verbose output and tablespace');
|
|
|
|
|
|
|
|
# REINDEX TABLESPACE on toast indexes and tables fails. This is not
|
|
|
|
# part of the main regression test suite as these have unpredictable
|
|
|
|
# names, and CONCURRENTLY cannot be used in transaction blocks, preventing
|
|
|
|
# the use of TRY/CATCH blocks in a custom function to filter error
|
|
|
|
# messages.
|
|
|
|
$node->command_checks_all(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '-t', $toast_table, '--tablespace',
|
2021-03-03 02:14:21 +01:00
|
|
|
$tbspace_name, 'postgres'
|
|
|
|
],
|
|
|
|
1,
|
|
|
|
[],
|
|
|
|
[qr/cannot move system relation/],
|
|
|
|
'reindex toast table with tablespace');
|
|
|
|
$node->command_checks_all(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '--concurrently', '-t', $toast_table,
|
|
|
|
'--tablespace', $tbspace_name, 'postgres'
|
2021-03-03 02:14:21 +01:00
|
|
|
],
|
|
|
|
1,
|
|
|
|
[],
|
|
|
|
[qr/cannot move system relation/],
|
|
|
|
'reindex toast table concurrently with tablespace');
|
|
|
|
$node->command_checks_all(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '-i', $toast_index, '--tablespace',
|
2021-03-03 02:14:21 +01:00
|
|
|
$tbspace_name, 'postgres'
|
|
|
|
],
|
|
|
|
1,
|
|
|
|
[],
|
|
|
|
[qr/cannot move system relation/],
|
|
|
|
'reindex toast index with tablespace');
|
|
|
|
$node->command_checks_all(
|
|
|
|
[
|
2023-05-19 23:24:48 +02:00
|
|
|
'reindexdb', '--concurrently', '-i', $toast_index,
|
|
|
|
'--tablespace', $tbspace_name, 'postgres'
|
2021-03-03 02:14:21 +01:00
|
|
|
],
|
|
|
|
1,
|
|
|
|
[],
|
|
|
|
[qr/cannot move system relation/],
|
|
|
|
'reindex toast index concurrently with tablespace');
|
2019-03-29 08:25:20 +01:00
|
|
|
|
|
|
|
# connection strings
|
2016-08-04 20:44:23 +02:00
|
|
|
$node->command_ok([qw(reindexdb --echo --table=pg_am dbname=template1)],
|
|
|
|
'reindexdb table with connection string');
|
|
|
|
$node->command_ok(
|
|
|
|
[qw(reindexdb --echo dbname=template1)],
|
|
|
|
'reindexdb database with connection string');
|
|
|
|
$node->command_ok(
|
|
|
|
[qw(reindexdb --echo --system dbname=template1)],
|
|
|
|
'reindexdb system with connection string');
|
2019-07-27 15:21:18 +02:00
|
|
|
|
|
|
|
# parallel processing
|
|
|
|
$node->safe_psql(
|
|
|
|
'postgres', q|
|
|
|
|
CREATE SCHEMA s1;
|
|
|
|
CREATE TABLE s1.t1(id integer);
|
|
|
|
CREATE INDEX ON s1.t1(id);
|
|
|
|
CREATE SCHEMA s2;
|
|
|
|
CREATE TABLE s2.t2(id integer);
|
|
|
|
CREATE INDEX ON s2.t2(id);
|
|
|
|
-- empty schema
|
|
|
|
CREATE SCHEMA s3;
|
|
|
|
|);
|
|
|
|
|
|
|
|
$node->command_fails(
|
|
|
|
[ 'reindexdb', '-j', '2', '-s', 'postgres' ],
|
|
|
|
'parallel reindexdb cannot process system catalogs');
|
|
|
|
$node->command_fails(
|
|
|
|
[ 'reindexdb', '-j', '2', '-i', 'i1', 'postgres' ],
|
|
|
|
'parallel reindexdb cannot process indexes');
|
|
|
|
# Note that the ordering of the commands is not stable, so the second
|
|
|
|
# command for s2.t2 is not checked after.
|
|
|
|
$node->issues_sql_like(
|
|
|
|
[ 'reindexdb', '-j', '2', '-S', 's1', '-S', 's2', 'postgres' ],
|
|
|
|
qr/statement:\ REINDEX TABLE s1.t1;/,
|
|
|
|
'parallel reindexdb for schemas does a per-table REINDEX');
|
|
|
|
$node->command_ok(
|
|
|
|
[ 'reindexdb', '-j', '2', '-S', 's3' ],
|
|
|
|
'parallel reindexdb with empty schema');
|
Rework logic and simplify syntax of REINDEX DATABASE/SYSTEM
Per discussion, this commit includes a couple of changes to these two
flavors of REINDEX:
* The grammar is changed to make the name of the object optional, hence
one can rebuild all the indexes of the wanted area by specifying only
"REINDEX DATABASE;" or "REINDEX SYSTEM;". Previously, the object name
was mandatory and had to match the name of the database on which the
command is issued.
* REINDEX DATABASE is changed to ignore catalogs, making this task only
possible with REINDEX SYSTEM. This is a historical change, but there
was no way to work only on the indexes of a database without touching
the catalogs. We have discussed more approaches here, like the addition
of an option to skip the catalogs without changing the original
behavior, but concluded that what we have here is for the best.
This builds on top of the TAP tests introduced in 5fb5b6c, showing the
change in behavior for REINDEX SYSTEM. reindexdb is updated so as we do
not issue an extra REINDEX SYSTEM when working on a database in the
non-concurrent case, something that was confusing when --concurrently
got introduced, so this simplifies the code.
Author: Simon Riggs
Reviewed-by: Ashutosh Bapat, Bernd Helmle, Álvaro Herrera, Cary Huang,
Michael Paquier
Discussion: https://postgr.es/m/CANbhV-H=NH6Om4-X6cRjDWfH_Mu1usqwkuYVp-hwdB_PSHWRfg@mail.gmail.com
2022-07-19 04:45:06 +02:00
|
|
|
$node->command_ok(
|
2019-07-27 15:21:18 +02:00
|
|
|
[ 'reindexdb', '-j', '2', '--concurrently', '-d', 'postgres' ],
|
Rework logic and simplify syntax of REINDEX DATABASE/SYSTEM
Per discussion, this commit includes a couple of changes to these two
flavors of REINDEX:
* The grammar is changed to make the name of the object optional, hence
one can rebuild all the indexes of the wanted area by specifying only
"REINDEX DATABASE;" or "REINDEX SYSTEM;". Previously, the object name
was mandatory and had to match the name of the database on which the
command is issued.
* REINDEX DATABASE is changed to ignore catalogs, making this task only
possible with REINDEX SYSTEM. This is a historical change, but there
was no way to work only on the indexes of a database without touching
the catalogs. We have discussed more approaches here, like the addition
of an option to skip the catalogs without changing the original
behavior, but concluded that what we have here is for the best.
This builds on top of the TAP tests introduced in 5fb5b6c, showing the
change in behavior for REINDEX SYSTEM. reindexdb is updated so as we do
not issue an extra REINDEX SYSTEM when working on a database in the
non-concurrent case, something that was confusing when --concurrently
got introduced, so this simplifies the code.
Author: Simon Riggs
Reviewed-by: Ashutosh Bapat, Bernd Helmle, Álvaro Herrera, Cary Huang,
Michael Paquier
Discussion: https://postgr.es/m/CANbhV-H=NH6Om4-X6cRjDWfH_Mu1usqwkuYVp-hwdB_PSHWRfg@mail.gmail.com
2022-07-19 04:45:06 +02:00
|
|
|
'parallel reindexdb on database, concurrently');
|
2022-02-11 20:54:44 +01:00
|
|
|
|
|
|
|
done_testing();
|