'postgres', q(
CREATE EXTENSION amcheck;
- CREATE SCHEMA test_amcheck;
- SET search_path = test_amcheck;
-
CREATE FUNCTION ok_cmp (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
SELECT
CASE WHEN $1 < $2 THEN -1
--- Check 1: uniqueness violation.
---
CREATE FUNCTION ok_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
- SELECT ok_cmp($1, $2);
+ SELECT public.ok_cmp($1, $2);
$$;
---
--- Make values 768 and 769 look equal.
---
CREATE FUNCTION bad_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
SELECT
CASE WHEN ($1 = 768 AND $2 = 769) OR
($1 = 769 AND $2 = 768) THEN 0
- ELSE ok_cmp($1, $2)
+ ELSE public.ok_cmp($1, $2)
END;
$$;
--- Check 2: uniqueness violation without deduplication.
---
CREATE FUNCTION ok_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
- SELECT ok_cmp($1, $2);
+ SELECT public.ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
SELECT
CASE WHEN $1 = $2 AND $1 = 400 THEN -1
- ELSE ok_cmp($1, $2)
+ ELSE public.ok_cmp($1, $2)
END;
$$;
--- Check 3: uniqueness violation with deduplication.
---
CREATE FUNCTION ok_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
- SELECT ok_cmp($1, $2);
+ SELECT public.ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+ RETURNS int LANGUAGE sql AS
$$
- SELECT bad_cmp2($1, $2);
+ SELECT public.bad_cmp2($1, $2);
$$;
---
# We have not yet broken the index, so we should get no corruption
$result = $node->safe_psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
+ SELECT bt_index_check('bttest_unique_idx1', true, true);
));
is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
# values to be equal.
$node->safe_psql(
'postgres', q(
- SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'bad_cmp1'::regproc
WHERE amproc = 'ok_cmp1'::regproc;
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
+ SELECT bt_index_check('bttest_unique_idx1', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
'detected uniqueness violation for index "bttest_unique_idx1"');
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
+ SELECT bt_index_check('bttest_unique_idx2', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx2"/,
'detected item order invariant violation for index "bttest_unique_idx2"');
$node->safe_psql(
'postgres', q(
- SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp2'::regproc
WHERE amproc = 'bad_cmp2'::regproc;
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
+ SELECT bt_index_check('bttest_unique_idx2', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
'detected uniqueness violation for index "bttest_unique_idx2"');
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
+ SELECT bt_index_check('bttest_unique_idx3', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
'detected item order invariant violation for index "bttest_unique_idx3"');
# with different visibility.
$node->safe_psql(
'postgres', q(
- SET search_path = test_amcheck;
DELETE FROM bttest_unique3 WHERE 380 <= i AND i <= 420;
INSERT INTO bttest_unique3 (SELECT * FROM generate_series(380, 420));
INSERT INTO bttest_unique3 VALUES (400);
$node->safe_psql(
'postgres', q(
- SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp3'::regproc
WHERE amproc = 'bad_cmp3'::regproc;
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
+ SELECT bt_index_check('bttest_unique_idx3', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx3"/,
'detected uniqueness violation for index "bttest_unique_idx3"');
SetUserIdAndSecContext(heaprel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
}
else
{
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
}
else
{
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
indexRelation = index_open(indexRelationId, RowExclusiveLock);
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- if (!IsBootstrapProcessingMode())
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/* Set up initial progress report status */
{
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
indexRelation = index_open(indexId, RowExclusiveLock);
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
if (progress)
{
SetUserIdAndSecContext(onerel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/* measure elapsed time iff autovacuum logging requires it */
if (AmAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
SetUserIdAndSecContext(OldHeap->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/*
* Since we may open a new transaction for each relation, we have to check
root_save_nestlevel = NewGUCNestLevel();
- if (!IsBootstrapProcessingMode())
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/*
* Some callers need us to run with an empty default_tablespace; this is a
SetUserIdAndSecContext(childrel->rd_rel->relowner,
child_save_sec_context | SECURITY_RESTRICTED_OPERATION);
child_save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/*
* Don't try to create indexes on foreign tables, though. Skip
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/* determine safety of this index for set_indexsafe_procflags */
idx->safe = (indexRel->rd_indexprs == NIL &&
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/* Make sure it is a materialized view. */
if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW)
SetUserIdAndSecContext(rel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
- PGC_S_SESSION);
+ RestrictSearchPath();
/*
* If PROCESS_MAIN is set (the default), it's time to vacuum the main
*/
#define REALTYPE_PRECISION 17
+/*
+ * Safe search path when executing code as the table owner, such as during
+ * maintenance operations.
+ */
+#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
+
static int GUC_check_errcode_value;
static List *reserved_class_prefix = NIL;
return ++GUCNestLevel;
}
+/*
+ * Set search_path to a fixed value for maintenance operations. No effect
+ * during bootstrap, when the search_path is already set to a fixed value and
+ * cannot be changed.
+ */
+void
+RestrictSearchPath(void)
+{
+ if (!IsBootstrapProcessingMode())
+ set_config_option("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false);
+}
+
/*
* Do GUC processing at transaction or subtransaction commit or abort, or
* when exiting a function that has proconfig settings, or when undoing a
#define GUC_QUALIFIER_SEPARATOR '.'
-/*
- * Safe search path when executing code as the table owner, such as during
- * maintenance operations.
- */
-#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
-
/*
* Bit values in "flags" of a GUC variable. Note that these don't appear
* on disk, so we can reassign their values freely.
extern void ResetAllOptions(void);
extern void AtStart_GUC(void);
extern int NewGUCNestLevel(void);
+extern void RestrictSearchPath(void);
extern void AtEOXact_GUC(bool isCommit, int nestLevel);
extern void BeginReportingGUCOptions(void);
extern void ReportChangedGUCOptions(void);