MemoryContextSwitchTo(oldcxt);
}
+/*
+ * EventTriggerStashAlterDefPrivs
+ * Save data about an ALTER DEFAULT PRIVILEGES command being
+ * executed
+ */
+void
+EventTriggerStashAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt)
+{
+ MemoryContext oldcxt;
+ StashedCommand *stashed;
+
+ if (currentEventTriggerState->commandCollectionInhibited)
+ return;
+
+ oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt);
+
+ stashed = palloc0(sizeof(StashedCommand));
+ stashed->type = SCT_AlterDefaultPrivileges;
+
+ switch (stmt->action->objtype)
+ {
+ case ACL_OBJECT_RELATION:
+ stashed->d.defprivs.objtype = "TABLES";
+ break;
+ case ACL_OBJECT_FUNCTION:
+ stashed->d.defprivs.objtype = "FUNCTIONS";
+ break;
+ case ACL_OBJECT_SEQUENCE:
+ stashed->d.defprivs.objtype = "SEQUENCES";
+ break;
+ case ACL_OBJECT_TYPE:
+ stashed->d.defprivs.objtype = "TYPES";
+ break;
+ default:
+ elog(ERROR, "unexpected object type %d", stmt->action->objtype);
+ }
+
+
+ stashed->in_extension = creating_extension;
+ stashed->parsetree = copyObject(stmt);
+
+ currentEventTriggerState->stash = lappend(currentEventTriggerState->stash,
+ stashed);
+ MemoryContextSwitchTo(oldcxt);
+}
+
Datum
pg_event_trigger_get_creation_commands(PG_FUNCTION_ARGS)
{
/* command */
values[i++] = CStringGetTextDatum(command);
}
+ else if (cmd->type == SCT_AlterDefaultPrivileges)
+ {
+ /* classid */
+ nulls[i++] = true;
+ /* objid */
+ nulls[i++] = true;
+ /* objsubid */
+ nulls[i++] = true;
+ /* command tag */
+ values[i++] = CStringGetTextDatum(CreateCommandTag(cmd->parsetree));
+ /* object_type */
+ values[i++] = CStringGetTextDatum(cmd->d.defprivs.objtype);
+ /* schema */
+ nulls[i++] = true;
+ /* identity */
+ nulls[i++] = true;
+ /* in_extension */
+ values[i++] = BoolGetDatum(cmd->in_extension);
+ /* command */
+ values[i++] = CStringGetTextDatum(command);
+ }
else
{
Assert(cmd->type == SCT_Grant);
return alterOpFam;
}
+static ObjTree *
+deparse_AlterDefaultPrivilegesStmt(StashedCommand *cmd)
+{
+ ObjTree *alterStmt;
+ AlterDefaultPrivilegesStmt *stmt = (AlterDefaultPrivilegesStmt *) cmd->parsetree;
+ List *roles = NIL;
+ List *schemas = NIL;
+ List *grantees;
+ List *privs;
+ ListCell *cell;
+ ObjTree *tmp;
+ ObjTree *grant;
+
+ alterStmt = new_objtree_VA("ALTER DEFAULT PRIVILEGES %{in_schema}s "
+ "%{for_roles}s %{grant}s", 0);
+
+ /* Scan the parse node to dig out the FOR ROLE and IN SCHEMA clauses */
+ foreach(cell, stmt->options)
+ {
+ DefElem *opt = (DefElem *) lfirst(cell);
+ ListCell *cell2;
+
+ Assert(IsA(opt, DefElem));
+ Assert(IsA(opt->arg, List));
+ if (strcmp(opt->defname, "roles") == 0)
+ {
+ foreach(cell2, (List *) opt->arg)
+ {
+ Value *val = lfirst(cell2);
+ ObjTree *obj = new_objtree_for_role(strVal(val));
+
+ roles = lappend(roles, new_object_object(obj));
+ }
+ }
+ else if (strcmp(opt->defname, "schemas") == 0)
+ {
+ foreach(cell2, (List *) opt->arg)
+ {
+ Value *val = lfirst(cell2);
+
+ schemas = lappend(schemas,
+ new_string_object(strVal(val)));
+ }
+ }
+ }
+
+ /* Add the FOR ROLE clause, if any */
+ tmp = new_objtree_VA("FOR ROLE %{roles:, }R", 0);
+ append_array_object(tmp, "roles", roles);
+ if (roles == NIL)
+ append_bool_object(tmp, "present", false);
+ append_object_object(alterStmt, "for_roles", tmp);
+
+ /* Add the IN SCHEMA clause, if any */
+ tmp = new_objtree_VA("IN SCHEMA %{schemas:, }I", 0);
+ append_array_object(tmp, "schemas", schemas);
+ if (schemas == NIL)
+ append_bool_object(tmp, "present", false);
+ append_object_object(alterStmt, "in_schema", tmp);
+
+ /* Add the GRANT subcommand */
+ if (stmt->action->is_grant)
+ grant = new_objtree_VA("GRANT %{privileges:, }s ON %{target}s "
+ "TO %{grantees:, }R %{grant_option}s", 0);
+ else
+ grant = new_objtree_VA("REVOKE %{grant_option}s %{privileges:, }s "
+ "ON %{target}s FROM %{grantees:, }R", 0);
+
+ /* add the GRANT OPTION clause */
+ tmp = new_objtree_VA(stmt->action->is_grant ?
+ "WITH GRANT OPTION" : "GRANT OPTION FOR",
+ 1, "present", ObjTypeBool,
+ stmt->action->grant_option);
+ append_object_object(grant, "grant_option", tmp);
+
+ /* add the target object type */
+ append_string_object(grant, "target", cmd->d.defprivs.objtype);
+
+ /* add the grantee list */
+ grantees = NIL;
+ foreach(cell, stmt->action->grantees)
+ {
+ RoleSpec *spec = (RoleSpec *) lfirst(cell);
+ ObjTree *obj = new_objtree_for_rolespec(spec);
+
+ grantees = lappend(grantees, new_object_object(obj));
+ }
+ append_array_object(grant, "grantees", grantees);
+
+ /*
+ * Add the privileges list. This uses the parser struct, as opposed to the
+ * InternalGrant format used by GRANT. There are enough other differences
+ * that this doesn't seem worth improving.
+ */
+ if (stmt->action->privileges == NIL)
+ privs = list_make1(new_string_object("ALL PRIVILEGES"));
+ else
+ {
+ privs = NIL;
+
+ foreach(cell, stmt->action->privileges)
+ {
+ AccessPriv *priv = lfirst(cell);
+
+ Assert(priv->cols == NIL);
+ privs = lappend(privs,
+ new_string_object(priv->priv_name));
+ }
+ }
+
+ append_array_object(grant, "privileges", privs);
+
+ append_object_object(alterStmt, "grant", grant);
+
+ return alterStmt;
+}
+
static ObjTree *
deparse_AlterTableStmt(StashedCommand *cmd)
{
break;
case T_AlterDefaultPrivilegesStmt:
- elog(ERROR, "unimplemented deparse of %s", CreateCommandTag(parsetree));
+ /* handled elsewhere */
+ elog(ERROR, "unexpected command type %s", CreateCommandTag(parsetree));
break;
case T_CreatePolicyStmt: /* CREATE POLICY */
case SCT_AlterOpFamily:
tree = deparse_AlterOpFamily(cmd);
break;
+ case SCT_AlterDefaultPrivileges:
+ tree = deparse_AlterDefaultPrivilegesStmt(cmd);
+ break;
default:
elog(ERROR, "unexpected deparse node type %d", cmd->type);
}