From 4a1a5491ce2f22bfb6c914577d5a949233d59ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCrkan=20=C4=B0ndibay?= Date: Fri, 1 Sep 2023 09:49:46 +0300 Subject: [PATCH] Refactors grant statements (#7153) DESCRIPTION: Refactors all grant statements to use common code blocks to deparse --- .../distributed/deparser/citus_grantutils.c | 110 ++++++++++++++++++ .../deparser/deparse_database_stmts.c | 36 +----- .../deparse_foreign_data_wrapper_stmts.c | 32 +---- .../deparser/deparse_foreign_server_stmts.c | 31 +---- .../deparser/deparse_function_stmts.c | 28 +---- .../distributed/deparser/deparse_role_stmts.c | 58 ++++----- .../deparser/deparse_schema_stmts.c | 28 +---- .../deparser/deparse_sequence_stmts.c | 28 +---- src/include/distributed/deparser.h | 12 ++ 9 files changed, 167 insertions(+), 196 deletions(-) create mode 100644 src/backend/distributed/deparser/citus_grantutils.c diff --git a/src/backend/distributed/deparser/citus_grantutils.c b/src/backend/distributed/deparser/citus_grantutils.c new file mode 100644 index 000000000..8e0dadff2 --- /dev/null +++ b/src/backend/distributed/deparser/citus_grantutils.c @@ -0,0 +1,110 @@ +#include "postgres.h" +#include "lib/stringinfo.h" +#include "nodes/parsenodes.h" +#include "distributed/deparser.h" +#include "distributed/citus_ruleutils.h" + +/* + * Append the 'WITH GRANT OPTION' clause to the given buffer if the given + * statement is a 'GRANT' statement and the grant option is specified. + */ +void +AppendWithGrantOption(StringInfo buf, GrantStmt *stmt) +{ + if (stmt->is_grant && stmt->grant_option) + { + appendStringInfo(buf, " WITH GRANT OPTION"); + } +} + + +/* + * Append the 'GRANT OPTION FOR' clause to the given buffer if the given + * statement is a 'REVOKE' statement and the grant option is specified. + */ +void +AppendGrantOptionFor(StringInfo buf, GrantStmt *stmt) +{ + if (!stmt->is_grant && stmt->grant_option) + { + appendStringInfo(buf, "GRANT OPTION FOR "); + } +} + + +/* + * Append the 'RESTRICT' or 'CASCADE' clause to the given buffer if the given + * statement is a 'REVOKE' statement and the behavior is specified. + */ +void +AppendGrantRestrictAndCascadeForRoleSpec(StringInfo buf, DropBehavior behavior, bool + isGrant) +{ + if (!isGrant) + { + if (behavior == DROP_RESTRICT) + { + appendStringInfo(buf, " RESTRICT"); + } + else if (behavior == DROP_CASCADE) + { + appendStringInfo(buf, " CASCADE"); + } + } +} + + +/* + * Append the 'RESTRICT' or 'CASCADE' clause to the given buffer using 'GrantStmt', + * if the given statement is a 'REVOKE' statement and the behavior is specified. + */ +void +AppendGrantRestrictAndCascade(StringInfo buf, GrantStmt *stmt) +{ + AppendGrantRestrictAndCascadeForRoleSpec(buf, stmt->behavior, stmt->is_grant); +} + + +/* + * Append the 'GRANTED BY' clause to the given buffer if the given statement is a + * 'GRANT' statement and the grantor is specified. + */ +void +AppendGrantedByInGrantForRoleSpec(StringInfo buf, RoleSpec *grantor, bool isGrant) +{ + if (isGrant && grantor) + { + appendStringInfo(buf, " GRANTED BY %s", RoleSpecString(grantor, true)); + } +} + + +/* + * Append the 'GRANTED BY' clause to the given buffer using 'GrantStmt', + * if the given statement is a 'GRANT' statement and the grantor is specified. + */ +void +AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt) +{ + AppendGrantedByInGrantForRoleSpec(buf, stmt->grantor, stmt->is_grant); +} + + +void +AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt) +{ + appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); + AppendGrantOptionFor(buf, stmt); + AppendGrantPrivileges(buf, stmt); +} + + +void +AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt) +{ + AppendGrantGrantees(buf, stmt); + AppendWithGrantOption(buf, stmt); + AppendGrantRestrictAndCascade(buf, stmt); + AppendGrantedByInGrant(buf, stmt); + appendStringInfo(buf, ";"); +} diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 24f618877..f1aaaa63b 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -18,8 +18,8 @@ #include "nodes/parsenodes.h" #include "utils/builtins.h" -#include "distributed/citus_ruleutils.h" #include "distributed/deparser.h" +#include "distributed/citus_ruleutils.h" static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt); @@ -74,41 +74,11 @@ AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt) { Assert(stmt->objtype == OBJECT_DATABASE); - appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); + AppendGrantSharedPrefix(buf, stmt); AppendGrantDatabases(buf, stmt); - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfo(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfo(buf, " CASCADE"); - } - } - - if (stmt->grantor) - { - appendStringInfo(buf, " GRANTED BY %s", RoleSpecString(stmt->grantor, true)); - } - - appendStringInfo(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/backend/distributed/deparser/deparse_foreign_data_wrapper_stmts.c b/src/backend/distributed/deparser/deparse_foreign_data_wrapper_stmts.c index b8f2574a4..3f755c905 100644 --- a/src/backend/distributed/deparser/deparse_foreign_data_wrapper_stmts.c +++ b/src/backend/distributed/deparser/deparse_foreign_data_wrapper_stmts.c @@ -21,7 +21,6 @@ static void AppendGrantOnFDWStmt(StringInfo buf, GrantStmt *stmt); static void AppendGrantOnFDWNames(StringInfo buf, GrantStmt *stmt); - char * DeparseGrantOnFDWStmt(Node *node) { @@ -41,36 +40,9 @@ static void AppendGrantOnFDWStmt(StringInfo buf, GrantStmt *stmt) { Assert(stmt->objtype == OBJECT_FDW); - - appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); - + AppendGrantSharedPrefix(buf, stmt); AppendGrantOnFDWNames(buf, stmt); - - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfo(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfo(buf, " CASCADE"); - } - } - appendStringInfo(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/backend/distributed/deparser/deparse_foreign_server_stmts.c b/src/backend/distributed/deparser/deparse_foreign_server_stmts.c index c1d2de7e9..403569b94 100644 --- a/src/backend/distributed/deparser/deparse_foreign_server_stmts.c +++ b/src/backend/distributed/deparser/deparse_foreign_server_stmts.c @@ -298,36 +298,9 @@ static void AppendGrantOnForeignServerStmt(StringInfo buf, GrantStmt *stmt) { Assert(stmt->objtype == OBJECT_FOREIGN_SERVER); - - appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); - + AppendGrantSharedPrefix(buf, stmt); AppendGrantOnForeignServerServers(buf, stmt); - - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfo(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfo(buf, " CASCADE"); - } - } - appendStringInfo(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/backend/distributed/deparser/deparse_function_stmts.c b/src/backend/distributed/deparser/deparse_function_stmts.c index 524a1928d..c1d7d3128 100644 --- a/src/backend/distributed/deparser/deparse_function_stmts.c +++ b/src/backend/distributed/deparser/deparse_function_stmts.c @@ -749,35 +749,11 @@ AppendGrantOnFunctionStmt(StringInfo buf, GrantStmt *stmt) "GRANT .. ALL FUNCTIONS/PROCEDURES IN SCHEMA is not supported for formatting."); } - appendStringInfoString(buf, stmt->is_grant ? "GRANT " : "REVOKE "); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfoString(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); + AppendGrantSharedPrefix(buf, stmt); AppendGrantOnFunctionFunctions(buf, stmt); - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfoString(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfoString(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfoString(buf, " CASCADE"); - } - } - appendStringInfoString(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/backend/distributed/deparser/deparse_role_stmts.c b/src/backend/distributed/deparser/deparse_role_stmts.c index 4ad4f4c7f..c1f1d769f 100644 --- a/src/backend/distributed/deparser/deparse_role_stmts.c +++ b/src/backend/distributed/deparser/deparse_role_stmts.c @@ -29,6 +29,8 @@ static void AppendRoleOption(StringInfo buf, ListCell *optionCell); static void AppendRoleList(StringInfo buf, List *roleList); static void AppendDropRoleStmt(StringInfo buf, DropRoleStmt *stmt); static void AppendGrantRoleStmt(StringInfo buf, GrantRoleStmt *stmt); +static void AppendRevokeAdminOptionFor(StringInfo buf, GrantRoleStmt *stmt); +static void AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt); /* @@ -342,14 +344,15 @@ DeparseGrantRoleStmt(Node *node) /* - * AppendGrantRoleStmt generates the string representation of the - * GrantRoleStmt and appends it to the buffer. + * Append the 'RESTRICT' or 'CASCADE' clause to the given buffer if the given + * statement is a 'REVOKE' statement and the behavior is specified. + * After PostgreSQL 16, the behavior is specified in the 'opt' field of + * GrantRoleStmt and may have multiple values. + * Here, compile time version is checked to support both versions. */ static void -AppendGrantRoleStmt(StringInfo buf, GrantRoleStmt *stmt) +AppendRevokeAdminOptionFor(StringInfo buf, GrantRoleStmt *stmt) { - appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); - #if PG_VERSION_NUM >= PG_VERSION_16 if (!stmt->is_grant) { @@ -369,13 +372,12 @@ AppendGrantRoleStmt(StringInfo buf, GrantRoleStmt *stmt) appendStringInfo(buf, "ADMIN OPTION FOR "); } #endif +} - AppendRoleList(buf, stmt->granted_roles); - - appendStringInfo(buf, "%s ", stmt->is_grant ? " TO " : " FROM "); - - AppendRoleList(buf, stmt->grantee_roles); +static void +AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt) +{ if (stmt->is_grant) { #if PG_VERSION_NUM >= PG_VERSION_16 @@ -394,23 +396,27 @@ AppendGrantRoleStmt(StringInfo buf, GrantRoleStmt *stmt) appendStringInfo(buf, " WITH ADMIN OPTION"); } #endif + } +} - if (stmt->grantor) - { - appendStringInfo(buf, " GRANTED BY %s", RoleSpecString(stmt->grantor, true)); - } - } - else - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfo(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfo(buf, " CASCADE"); - } - } + +/* + * AppendGrantRoleStmt generates the string representation of the + * GrantRoleStmt and appends it to the buffer. + */ +static void +AppendGrantRoleStmt(StringInfo buf, GrantRoleStmt *stmt) +{ + appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); + AppendRevokeAdminOptionFor(buf, stmt); + AppendRoleList(buf, stmt->granted_roles); + appendStringInfo(buf, "%s ", stmt->is_grant ? " TO " : " FROM "); + AppendRoleList(buf, stmt->grantee_roles); + AppendGrantWithAdminOption(buf, stmt); + AppendGrantedByInGrantForRoleSpec(buf, stmt->grantor, stmt->is_grant); + AppendGrantRestrictAndCascadeForRoleSpec(buf, stmt->behavior, stmt->is_grant); + AppendGrantedByInGrantForRoleSpec(buf, stmt->grantor, stmt->is_grant); + appendStringInfo(buf, ";"); } diff --git a/src/backend/distributed/deparser/deparse_schema_stmts.c b/src/backend/distributed/deparser/deparse_schema_stmts.c index cf8bf3418..10317b899 100644 --- a/src/backend/distributed/deparser/deparse_schema_stmts.c +++ b/src/backend/distributed/deparser/deparse_schema_stmts.c @@ -178,35 +178,11 @@ AppendGrantOnSchemaStmt(StringInfo buf, GrantStmt *stmt) { Assert(stmt->objtype == OBJECT_SCHEMA); - appendStringInfo(buf, "%s ", stmt->is_grant ? "GRANT" : "REVOKE"); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); + AppendGrantSharedPrefix(buf, stmt); AppendGrantOnSchemaSchemas(buf, stmt); - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfo(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfo(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfo(buf, " CASCADE"); - } - } - appendStringInfo(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/backend/distributed/deparser/deparse_sequence_stmts.c b/src/backend/distributed/deparser/deparse_sequence_stmts.c index de2afdeec..98488c160 100644 --- a/src/backend/distributed/deparser/deparse_sequence_stmts.c +++ b/src/backend/distributed/deparser/deparse_sequence_stmts.c @@ -389,35 +389,11 @@ AppendGrantOnSequenceStmt(StringInfo buf, GrantStmt *stmt) "GRANT .. ALL SEQUENCES IN SCHEMA is not supported for formatting."); } - appendStringInfoString(buf, stmt->is_grant ? "GRANT " : "REVOKE "); - - if (!stmt->is_grant && stmt->grant_option) - { - appendStringInfoString(buf, "GRANT OPTION FOR "); - } - - AppendGrantPrivileges(buf, stmt); + AppendGrantSharedPrefix(buf, stmt); AppendGrantOnSequenceSequences(buf, stmt); - AppendGrantGrantees(buf, stmt); - - if (stmt->is_grant && stmt->grant_option) - { - appendStringInfoString(buf, " WITH GRANT OPTION"); - } - if (!stmt->is_grant) - { - if (stmt->behavior == DROP_RESTRICT) - { - appendStringInfoString(buf, " RESTRICT"); - } - else if (stmt->behavior == DROP_CASCADE) - { - appendStringInfoString(buf, " CASCADE"); - } - } - appendStringInfoString(buf, ";"); + AppendGrantSharedSuffix(buf, stmt); } diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 5eb751d23..85e6b9de0 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -109,6 +109,18 @@ extern char * DeparseAlterSchemaOwnerStmt(Node *node); extern void AppendGrantPrivileges(StringInfo buf, GrantStmt *stmt); extern void AppendGrantGrantees(StringInfo buf, GrantStmt *stmt); +extern void AppendWithGrantOption(StringInfo buf, GrantStmt *stmt); +extern void AppendGrantOptionFor(StringInfo buf, GrantStmt *stmt); +extern void AppendGrantRestrictAndCascadeForRoleSpec(StringInfo buf, DropBehavior + behavior, bool isGrant); +extern void AppendGrantRestrictAndCascade(StringInfo buf, GrantStmt *stmt); +extern void AppendGrantedByInGrantForRoleSpec(StringInfo buf, RoleSpec *grantor, bool + isGrant); +extern void AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt); + +extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt); +extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt); + /* forward declarations for deparse_statistics_stmts.c */ extern char * DeparseCreateStatisticsStmt(Node *node);