initdb: Refactor PG_CMD_PUTS loops
Keeping the SQL commands that initdb runs in string arrays before feeding them to PG_CMD_PUTS() seems unnecessarily verbose and inflexible. In some cases, the array only has one member. In other cases, one might want to use PG_CMD_PRINTF() instead, to parametrize a command, but that would require breaking up the loop or using workarounds like replace_token(). Unwind all that; it's much simpler that way. Reviewed-by: John Naylor <john.naylor@enterprisedb.com> Reviewed-by: Andrew Dunstan <andrew@dunslane.net> Discussion: https://www.postgresql.org/message-id/flat/2c50823b-f453-bb97-e38b-34751c51dcdf%40enterprisedb.com
This commit is contained in:
parent
d69d01ba9d
commit
1bd47d0dca
@ -1350,18 +1350,11 @@ bootstrap_template1(void)
|
|||||||
static void
|
static void
|
||||||
setup_auth(FILE *cmdfd)
|
setup_auth(FILE *cmdfd)
|
||||||
{
|
{
|
||||||
const char *const *line;
|
/*
|
||||||
static const char *const pg_authid_setup[] = {
|
* The authid table shouldn't be readable except through views, to
|
||||||
/*
|
* ensure passwords are not publicly visible.
|
||||||
* The authid table shouldn't be readable except through views, to
|
*/
|
||||||
* ensure passwords are not publicly visible.
|
PG_CMD_PUTS("REVOKE ALL ON pg_authid FROM public;\n\n");
|
||||||
*/
|
|
||||||
"REVOKE ALL ON pg_authid FROM public;\n\n",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (line = pg_authid_setup; *line != NULL; line++)
|
|
||||||
PG_CMD_PUTS(*line);
|
|
||||||
|
|
||||||
if (superuser_password)
|
if (superuser_password)
|
||||||
PG_CMD_PRINTF("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
|
PG_CMD_PRINTF("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
|
||||||
@ -1433,18 +1426,11 @@ get_su_pwd(void)
|
|||||||
static void
|
static void
|
||||||
setup_depend(FILE *cmdfd)
|
setup_depend(FILE *cmdfd)
|
||||||
{
|
{
|
||||||
const char *const *line;
|
/*
|
||||||
static const char *const pg_depend_setup[] = {
|
* Advance the OID counter so that subsequently-created objects aren't
|
||||||
/*
|
* pinned.
|
||||||
* Advance the OID counter so that subsequently-created objects aren't
|
*/
|
||||||
* pinned.
|
PG_CMD_PUTS("SELECT pg_stop_making_pinned_objects();\n\n");
|
||||||
*/
|
|
||||||
"SELECT pg_stop_making_pinned_objects();\n\n",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (line = pg_depend_setup; *line != NULL; line++)
|
|
||||||
PG_CMD_PUTS(*line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1530,147 +1516,138 @@ setup_collation(FILE *cmdfd)
|
|||||||
static void
|
static void
|
||||||
setup_privileges(FILE *cmdfd)
|
setup_privileges(FILE *cmdfd)
|
||||||
{
|
{
|
||||||
char **line;
|
PG_CMD_PRINTF("UPDATE pg_class "
|
||||||
char **priv_lines;
|
" SET relacl = (SELECT array_agg(a.acl) FROM "
|
||||||
static char *privileges_setup[] = {
|
" (SELECT E'=r/\"%s\"' as acl "
|
||||||
"UPDATE pg_class "
|
" UNION SELECT unnest(pg_catalog.acldefault("
|
||||||
" SET relacl = (SELECT array_agg(a.acl) FROM "
|
" CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' "
|
||||||
" (SELECT E'=r/\"$POSTGRES_SUPERUSERNAME\"' as acl "
|
" ELSE 'r' END::\"char\"," CppAsString2(BOOTSTRAP_SUPERUSERID) "::oid))"
|
||||||
" UNION SELECT unnest(pg_catalog.acldefault("
|
" ) as a) "
|
||||||
" CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' "
|
" WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
||||||
" ELSE 'r' END::\"char\"," CppAsString2(BOOTSTRAP_SUPERUSERID) "::oid))"
|
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
||||||
" ) as a) "
|
CppAsString2(RELKIND_SEQUENCE) ")"
|
||||||
" WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
" AND relacl IS NULL;\n\n",
|
||||||
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
escape_quotes(username));
|
||||||
CppAsString2(RELKIND_SEQUENCE) ")"
|
PG_CMD_PUTS("GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n\n");
|
||||||
" AND relacl IS NULL;\n\n",
|
PG_CMD_PUTS("REVOKE ALL ON pg_largeobject FROM PUBLIC;\n\n");
|
||||||
"GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n\n",
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
"REVOKE ALL ON pg_largeobject FROM PUBLIC;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
|
||||||
" oid,"
|
" 0,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
|
" relacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" relacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_class"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_class"
|
" relacl IS NOT NULL"
|
||||||
" WHERE"
|
" AND relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
||||||
" relacl IS NOT NULL"
|
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
||||||
" AND relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
CppAsString2(RELKIND_SEQUENCE) ");\n\n");
|
||||||
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
CppAsString2(RELKIND_SEQUENCE) ");\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" pg_class.oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
|
||||||
" pg_class.oid,"
|
" pg_attribute.attnum,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
|
" pg_attribute.attacl,"
|
||||||
" pg_attribute.attnum,"
|
" 'i'"
|
||||||
" pg_attribute.attacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_class"
|
||||||
" FROM"
|
" JOIN pg_attribute ON (pg_class.oid = pg_attribute.attrelid)"
|
||||||
" pg_class"
|
" WHERE"
|
||||||
" JOIN pg_attribute ON (pg_class.oid = pg_attribute.attrelid)"
|
" pg_attribute.attacl IS NOT NULL"
|
||||||
" WHERE"
|
" AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
||||||
" pg_attribute.attacl IS NOT NULL"
|
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
||||||
" AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
|
CppAsString2(RELKIND_SEQUENCE) ");\n\n");
|
||||||
CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
CppAsString2(RELKIND_SEQUENCE) ");\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_proc'),"
|
||||||
" oid,"
|
" 0,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_proc'),"
|
" proacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" proacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_proc"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_proc"
|
" proacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" proacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_type'),"
|
||||||
" oid,"
|
" 0,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_type'),"
|
" typacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" typacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_type"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_type"
|
" typacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" typacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_language'),"
|
||||||
" oid,"
|
" 0,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_language'),"
|
" lanacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" lanacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_language"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_language"
|
" lanacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" lanacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE "
|
||||||
" oid,"
|
" relname = 'pg_largeobject_metadata'),"
|
||||||
" (SELECT oid FROM pg_class WHERE "
|
" 0,"
|
||||||
" relname = 'pg_largeobject_metadata'),"
|
" lomacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" lomacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_largeobject_metadata"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_largeobject_metadata"
|
" lomacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" lomacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE relname = 'pg_namespace'),"
|
||||||
" oid,"
|
" 0,"
|
||||||
" (SELECT oid FROM pg_class WHERE relname = 'pg_namespace'),"
|
" nspacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" nspacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_namespace"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_namespace"
|
" nspacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" nspacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class WHERE "
|
||||||
" oid,"
|
" relname = 'pg_foreign_data_wrapper'),"
|
||||||
" (SELECT oid FROM pg_class WHERE "
|
" 0,"
|
||||||
" relname = 'pg_foreign_data_wrapper'),"
|
" fdwacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" fdwacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_foreign_data_wrapper"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_foreign_data_wrapper"
|
" fdwacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
PG_CMD_PUTS("INSERT INTO pg_init_privs "
|
||||||
" fdwacl IS NOT NULL;\n\n",
|
" (objoid, classoid, objsubid, initprivs, privtype)"
|
||||||
"INSERT INTO pg_init_privs "
|
" SELECT"
|
||||||
" (objoid, classoid, objsubid, initprivs, privtype)"
|
" oid,"
|
||||||
" SELECT"
|
" (SELECT oid FROM pg_class "
|
||||||
" oid,"
|
" WHERE relname = 'pg_foreign_server'),"
|
||||||
" (SELECT oid FROM pg_class "
|
" 0,"
|
||||||
" WHERE relname = 'pg_foreign_server'),"
|
" srvacl,"
|
||||||
" 0,"
|
" 'i'"
|
||||||
" srvacl,"
|
" FROM"
|
||||||
" 'i'"
|
" pg_foreign_server"
|
||||||
" FROM"
|
" WHERE"
|
||||||
" pg_foreign_server"
|
" srvacl IS NOT NULL;\n\n");
|
||||||
" WHERE"
|
|
||||||
" srvacl IS NOT NULL;\n\n",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
|
|
||||||
escape_quotes(username));
|
|
||||||
for (line = priv_lines; *line != NULL; line++)
|
|
||||||
PG_CMD_PUTS(*line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1746,8 +1723,6 @@ vacuum_db(FILE *cmdfd)
|
|||||||
static void
|
static void
|
||||||
make_template0(FILE *cmdfd)
|
make_template0(FILE *cmdfd)
|
||||||
{
|
{
|
||||||
const char *const *line;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pg_upgrade tries to preserve database OIDs across upgrades. It's smart
|
* pg_upgrade tries to preserve database OIDs across upgrades. It's smart
|
||||||
* enough to drop and recreate a conflicting database with the same name,
|
* enough to drop and recreate a conflicting database with the same name,
|
||||||
@ -1765,42 +1740,36 @@ make_template0(FILE *cmdfd)
|
|||||||
* are cheap. "STRATEGY = wal_log" would generate more WAL, which would be
|
* are cheap. "STRATEGY = wal_log" would generate more WAL, which would be
|
||||||
* a little bit slower and make the new cluster a little bit bigger.
|
* a little bit slower and make the new cluster a little bit bigger.
|
||||||
*/
|
*/
|
||||||
static const char *const template0_setup[] = {
|
PG_CMD_PUTS("CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false"
|
||||||
"CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false"
|
" OID = " CppAsString2(Template0DbOid)
|
||||||
" OID = " CppAsString2(Template0DbOid)
|
" STRATEGY = file_copy;\n\n");
|
||||||
" STRATEGY = file_copy;\n\n",
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* template0 shouldn't have any collation-dependent objects, so unset
|
* template0 shouldn't have any collation-dependent objects, so unset
|
||||||
* the collation version. This disables collation version checks when
|
* the collation version. This disables collation version checks when
|
||||||
* making a new database from it.
|
* making a new database from it.
|
||||||
*/
|
*/
|
||||||
"UPDATE pg_database SET datcollversion = NULL WHERE datname = 'template0';\n\n",
|
PG_CMD_PUTS("UPDATE pg_database SET datcollversion = NULL WHERE datname = 'template0';\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* While we are here, do set the collation version on template1.
|
* While we are here, do set the collation version on template1.
|
||||||
*/
|
*/
|
||||||
"UPDATE pg_database SET datcollversion = pg_database_collation_actual_version(oid) WHERE datname = 'template1';\n\n",
|
PG_CMD_PUTS("UPDATE pg_database SET datcollversion = pg_database_collation_actual_version(oid) WHERE datname = 'template1';\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Explicitly revoke public create-schema and create-temp-table
|
* Explicitly revoke public create-schema and create-temp-table
|
||||||
* privileges in template1 and template0; else the latter would be on
|
* privileges in template1 and template0; else the latter would be on
|
||||||
* by default
|
* by default
|
||||||
*/
|
*/
|
||||||
"REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n\n",
|
PG_CMD_PUTS("REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n\n");
|
||||||
"REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n\n",
|
PG_CMD_PUTS("REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n\n");
|
||||||
|
|
||||||
"COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n\n",
|
PG_CMD_PUTS("COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally vacuum to clean up dead rows in pg_database
|
* Finally vacuum to clean up dead rows in pg_database
|
||||||
*/
|
*/
|
||||||
"VACUUM pg_database;\n\n",
|
PG_CMD_PUTS("VACUUM pg_database;\n\n");
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (line = template0_setup; *line; line++)
|
|
||||||
PG_CMD_PUTS(*line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1809,21 +1778,13 @@ make_template0(FILE *cmdfd)
|
|||||||
static void
|
static void
|
||||||
make_postgres(FILE *cmdfd)
|
make_postgres(FILE *cmdfd)
|
||||||
{
|
{
|
||||||
const char *const *line;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just as we did for template0, and for the same reasons, assign a fixed
|
* Just as we did for template0, and for the same reasons, assign a fixed
|
||||||
* OID to postgres and select the file_copy strategy.
|
* OID to postgres and select the file_copy strategy.
|
||||||
*/
|
*/
|
||||||
static const char *const postgres_setup[] = {
|
PG_CMD_PUTS("CREATE DATABASE postgres OID = " CppAsString2(PostgresDbOid)
|
||||||
"CREATE DATABASE postgres OID = " CppAsString2(PostgresDbOid)
|
" STRATEGY = file_copy;\n\n");
|
||||||
" STRATEGY = file_copy;\n\n",
|
PG_CMD_PUTS("COMMENT ON DATABASE postgres IS 'default administrative connection database';\n\n");
|
||||||
"COMMENT ON DATABASE postgres IS 'default administrative connection database';\n\n",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (line = postgres_setup; *line; line++)
|
|
||||||
PG_CMD_PUTS(*line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user