2004-01-11 05:58:17 +01:00
|
|
|
--
|
|
|
|
-- Regression tests for schemas (namespaces)
|
|
|
|
--
|
2023-05-08 15:14:07 +02:00
|
|
|
-- set the whitespace-only search_path to test that the
|
|
|
|
-- GUC list syntax is preserved during a schema creation
|
|
|
|
SELECT pg_catalog.set_config('search_path', ' ', false);
|
|
|
|
set_config
|
|
|
|
------------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
2018-03-15 19:00:31 +01:00
|
|
|
CREATE SCHEMA test_ns_schema_1
|
2004-01-11 05:58:17 +01:00
|
|
|
CREATE UNIQUE INDEX abc_a_idx ON abc (a)
|
|
|
|
CREATE VIEW abc_view AS
|
|
|
|
SELECT a+1 AS a, b+1 AS b FROM abc
|
|
|
|
CREATE TABLE abc (
|
|
|
|
a serial,
|
|
|
|
b int UNIQUE
|
|
|
|
);
|
2023-05-08 15:14:07 +02:00
|
|
|
-- verify that the correct search_path restored on abort
|
|
|
|
SET search_path to public;
|
|
|
|
BEGIN;
|
|
|
|
SET search_path to public, test_ns_schema_1;
|
|
|
|
CREATE SCHEMA test_ns_schema_2
|
|
|
|
CREATE VIEW abc_view AS SELECT c FROM abc;
|
|
|
|
ERROR: column "c" does not exist
|
|
|
|
LINE 2: CREATE VIEW abc_view AS SELECT c FROM abc;
|
|
|
|
^
|
|
|
|
COMMIT;
|
|
|
|
SHOW search_path;
|
|
|
|
search_path
|
|
|
|
-------------
|
|
|
|
public
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- verify that the correct search_path preserved
|
|
|
|
-- after creating the schema and on commit
|
|
|
|
BEGIN;
|
|
|
|
SET search_path to public, test_ns_schema_1;
|
|
|
|
CREATE SCHEMA test_ns_schema_2
|
|
|
|
CREATE VIEW abc_view AS SELECT a FROM abc;
|
|
|
|
SHOW search_path;
|
|
|
|
search_path
|
|
|
|
--------------------------
|
|
|
|
public, test_ns_schema_1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
COMMIT;
|
|
|
|
SHOW search_path;
|
|
|
|
search_path
|
|
|
|
--------------------------
|
|
|
|
public, test_ns_schema_1
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
DROP SCHEMA test_ns_schema_2 CASCADE;
|
|
|
|
NOTICE: drop cascades to view test_ns_schema_2.abc_view
|
2004-01-11 05:58:17 +01:00
|
|
|
-- verify that the objects were created
|
|
|
|
SELECT COUNT(*) FROM pg_class WHERE relnamespace =
|
2018-03-15 19:00:31 +01:00
|
|
|
(SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1');
|
2004-01-11 05:58:17 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
5
|
|
|
|
(1 row)
|
|
|
|
|
2018-03-15 19:00:31 +01:00
|
|
|
INSERT INTO test_ns_schema_1.abc DEFAULT VALUES;
|
|
|
|
INSERT INTO test_ns_schema_1.abc DEFAULT VALUES;
|
|
|
|
INSERT INTO test_ns_schema_1.abc DEFAULT VALUES;
|
|
|
|
SELECT * FROM test_ns_schema_1.abc;
|
2004-01-11 05:58:17 +01:00
|
|
|
a | b
|
|
|
|
---+---
|
|
|
|
1 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
(3 rows)
|
|
|
|
|
2018-03-15 19:00:31 +01:00
|
|
|
SELECT * FROM test_ns_schema_1.abc_view;
|
2004-01-11 05:58:17 +01:00
|
|
|
a | b
|
|
|
|
---+---
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
(3 rows)
|
|
|
|
|
2018-03-15 19:00:31 +01:00
|
|
|
ALTER SCHEMA test_ns_schema_1 RENAME TO test_ns_schema_renamed;
|
2013-12-11 21:45:15 +01:00
|
|
|
SELECT COUNT(*) FROM pg_class WHERE relnamespace =
|
2018-03-15 19:00:31 +01:00
|
|
|
(SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1');
|
2013-12-11 21:45:15 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
2012-10-04 01:47:11 +02:00
|
|
|
-- test IF NOT EXISTS cases
|
2018-03-15 19:00:31 +01:00
|
|
|
CREATE SCHEMA test_ns_schema_renamed; -- fail, already exists
|
|
|
|
ERROR: schema "test_ns_schema_renamed" already exists
|
|
|
|
CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed; -- ok with notice
|
|
|
|
NOTICE: schema "test_ns_schema_renamed" already exists, skipping
|
|
|
|
CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed -- fail, disallowed
|
2012-10-04 01:47:11 +02:00
|
|
|
CREATE TABLE abc (
|
|
|
|
a serial,
|
|
|
|
b int UNIQUE
|
|
|
|
);
|
|
|
|
ERROR: CREATE SCHEMA IF NOT EXISTS cannot include schema elements
|
2012-10-04 23:14:59 +02:00
|
|
|
LINE 2: CREATE TABLE abc (
|
|
|
|
^
|
2018-03-15 19:00:31 +01:00
|
|
|
DROP SCHEMA test_ns_schema_renamed CASCADE;
|
2008-06-11 23:53:49 +02:00
|
|
|
NOTICE: drop cascades to 2 other objects
|
2018-03-15 19:00:31 +01:00
|
|
|
DETAIL: drop cascades to table test_ns_schema_renamed.abc
|
|
|
|
drop cascades to view test_ns_schema_renamed.abc_view
|
2004-01-11 05:58:17 +01:00
|
|
|
-- verify that the objects were dropped
|
|
|
|
SELECT COUNT(*) FROM pg_class WHERE relnamespace =
|
2018-03-15 19:00:31 +01:00
|
|
|
(SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_renamed');
|
2004-01-11 05:58:17 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
0
|
|
|
|
(1 row)
|
|
|
|
|
Fix search_path to a safe value during maintenance operations.
While executing maintenance operations (ANALYZE, CLUSTER, REFRESH
MATERIALIZED VIEW, REINDEX, or VACUUM), set search_path to
'pg_catalog, pg_temp' to prevent inconsistent behavior.
Functions that are used for functional indexes, in index expressions,
or in materialized views and depend on a different search path must be
declared with CREATE FUNCTION ... SET search_path='...'.
This change was previously committed as 05e1737351, then reverted in
commit 2fcc7ee7af because it was too late in the cycle.
Preparation for the MAINTAIN privilege, which was previously reverted
due to search_path manipulation hazards.
Discussion: https://postgr.es/m/d4ccaf3658cb3c281ec88c851a09733cd9482f22.camel@j-davis.com
Discussion: https://postgr.es/m/E1q7j7Y-000z1H-Hr%40gemulon.postgresql.org
Discussion: https://postgr.es/m/e44327179e5c9015c8dda67351c04da552066017.camel%40j-davis.com
Reviewed-by: Greg Stark, Nathan Bossart, Noah Misch
2024-03-05 02:31:38 +01:00
|
|
|
--
|
|
|
|
-- Verify that search_path is set to a safe value during maintenance
|
|
|
|
-- commands.
|
|
|
|
--
|
|
|
|
CREATE SCHEMA test_maint_search_path;
|
|
|
|
SET search_path = test_maint_search_path;
|
|
|
|
CREATE FUNCTION fn(INT) RETURNS INT IMMUTABLE LANGUAGE plpgsql AS $$
|
|
|
|
BEGIN
|
|
|
|
RAISE NOTICE 'current search_path: %', current_setting('search_path');
|
|
|
|
RETURN $1;
|
|
|
|
END;
|
|
|
|
$$;
|
|
|
|
CREATE TABLE test_maint(i INT);
|
|
|
|
INSERT INTO test_maint VALUES (1), (2);
|
|
|
|
CREATE MATERIALIZED VIEW test_maint_mv AS SELECT fn(i) FROM test_maint;
|
|
|
|
NOTICE: current search_path: test_maint_search_path
|
|
|
|
NOTICE: current search_path: test_maint_search_path
|
|
|
|
-- the following commands should see search_path as pg_catalog, pg_temp
|
|
|
|
CREATE INDEX test_maint_idx ON test_maint_search_path.test_maint (fn(i));
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
REINDEX TABLE test_maint_search_path.test_maint;
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
ANALYZE test_maint_search_path.test_maint;
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
VACUUM FULL test_maint_search_path.test_maint;
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
CLUSTER test_maint_search_path.test_maint USING test_maint_idx;
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
REFRESH MATERIALIZED VIEW test_maint_search_path.test_maint_mv;
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
NOTICE: current search_path: pg_catalog, pg_temp
|
|
|
|
RESET search_path;
|
|
|
|
DROP SCHEMA test_maint_search_path CASCADE;
|
|
|
|
NOTICE: drop cascades to 3 other objects
|
|
|
|
DETAIL: drop cascades to function test_maint_search_path.fn(integer)
|
|
|
|
drop cascades to table test_maint_search_path.test_maint
|
|
|
|
drop cascades to materialized view test_maint_search_path.test_maint_mv
|