mirror of
https://github.com/postgres/postgres.git
synced 2026-04-09 02:56:13 -04:00
Add a new SQL-callable function that returns the DDL statements needed to recreate a database. It takes a regdatabase argument and an optional VARIADIC text argument for options that are specified as alternating name/value pairs. The following options are supported: pretty (boolean) for formatted output, owner (boolean) to include OWNER and tablespace (boolean) to include TABLESPACE. The return is one or multiple rows where the first row is a CREATE DATABASE statement and subsequent rows are ALTER DATABASE statements to set some database properties. The caller must have CONNECT privilege on the target database. Author: Akshay Joshi <akshay.joshi@enterprisedb.com> Co-authored-by: Andrew Dunstan <andrew@dunslane.net> Co-authored-by: Euler Taveira <euler@eulerto.com> Reviewed-by: Japin Li <japinli@hotmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Reviewed-by: Quan Zongliang <quanzongliang@yeah.net> Discussion: https://postgr.es/m/CANxoLDc6FHBYJvcgOnZyS+jF0NUo3Lq_83-rttBuJgs9id_UDg@mail.gmail.com Discussion: https://postgr.es/m/e247c261-e3fb-4810-81e0-a65893170e94@dunslane.net
66 lines
2.3 KiB
PL/PgSQL
66 lines
2.3 KiB
PL/PgSQL
--
|
|
-- Tests for pg_get_database_ddl()
|
|
--
|
|
|
|
-- To produce stable regression test output, strip locale/collation details
|
|
-- from the DDL output. Uses a plain SQL function to avoid a PL/pgSQL
|
|
-- dependency.
|
|
|
|
CREATE OR REPLACE FUNCTION ddl_filter(ddl_input TEXT)
|
|
RETURNS TEXT LANGUAGE sql AS $$
|
|
SELECT regexp_replace(
|
|
regexp_replace(
|
|
regexp_replace(
|
|
regexp_replace(
|
|
regexp_replace(
|
|
ddl_input,
|
|
'\s*\mLOCALE_PROVIDER\M\s*=\s*([''"]?[^''"\s]+[''"]?)', '', 'gi'),
|
|
'\s*LC_COLLATE\s*=\s*([''"])[^''"]*\1', '', 'gi'),
|
|
'\s*LC_CTYPE\s*=\s*([''"])[^''"]*\1', '', 'gi'),
|
|
'\s*\S*LOCALE\S*\s*=?\s*([''"])[^''"]*\1', '', 'gi'),
|
|
'\s*\S*COLLATION\S*\s*=?\s*([''"])[^''"]*\1', '', 'gi')
|
|
$$;
|
|
|
|
CREATE ROLE regress_datdba;
|
|
CREATE DATABASE regress_database_ddl
|
|
ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0
|
|
OWNER regress_datdba;
|
|
ALTER DATABASE regress_database_ddl CONNECTION_LIMIT 123;
|
|
ALTER DATABASE regress_database_ddl SET random_page_cost = 2.0;
|
|
ALTER ROLE regress_datdba IN DATABASE regress_database_ddl SET random_page_cost = 1.1;
|
|
|
|
-- Database doesn't exist
|
|
SELECT * FROM pg_get_database_ddl('regression_database');
|
|
|
|
-- NULL value
|
|
SELECT * FROM pg_get_database_ddl(NULL);
|
|
|
|
-- Invalid option value (should error)
|
|
SELECT * FROM pg_get_database_ddl('regress_database_ddl', 'owner', 'invalid');
|
|
|
|
-- Duplicate option (should error)
|
|
SELECT * FROM pg_get_database_ddl('regress_database_ddl', 'owner', 'false', 'owner', 'true');
|
|
|
|
-- Without options
|
|
SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regress_database_ddl');
|
|
|
|
-- With owner
|
|
SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regress_database_ddl', 'owner', 'true');
|
|
|
|
-- Pretty-printed output
|
|
\pset format unaligned
|
|
SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regress_database_ddl', 'pretty', 'true', 'tablespace', 'false');
|
|
\pset format aligned
|
|
|
|
-- Permission check: revoke CONNECT on database
|
|
CREATE ROLE regress_db_ddl_noaccess;
|
|
REVOKE CONNECT ON DATABASE regress_database_ddl FROM PUBLIC;
|
|
SET ROLE regress_db_ddl_noaccess;
|
|
SELECT * FROM pg_get_database_ddl('regress_database_ddl'); -- should fail
|
|
RESET ROLE;
|
|
GRANT CONNECT ON DATABASE regress_database_ddl TO PUBLIC;
|
|
DROP ROLE regress_db_ddl_noaccess;
|
|
|
|
DROP DATABASE regress_database_ddl;
|
|
DROP FUNCTION ddl_filter(text);
|
|
DROP ROLE regress_datdba;
|