citus/src/backend/distributed/deparser/deparse_schema_stmts.c

257 lines
5.3 KiB
C

/*-------------------------------------------------------------------------
*
* deparse_schema_stmts.c
* All routines to deparse schema statements.
* This file contains all entry points specific for schema statement deparsing
* as well as functions that are currently only used for deparsing of the
* schema statements.
*
* Copyright (c) Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "lib/stringinfo.h"
#include "nodes/nodes.h"
#include "utils/builtins.h"
#include "distributed/citus_ruleutils.h"
#include "distributed/deparser.h"
#include "distributed/listutils.h"
static void AppendCreateSchemaStmt(StringInfo buf, CreateSchemaStmt *stmt);
static void AppendDropSchemaStmt(StringInfo buf, DropStmt *stmt);
static void AppendGrantOnSchemaStmt(StringInfo buf, GrantStmt *stmt);
static void AppendGrantOnSchemaSchemas(StringInfo buf, GrantStmt *stmt);
static void AppendAlterSchemaRenameStmt(StringInfo buf, RenameStmt *stmt);
static void AppendAlterSchemaOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
char *
DeparseCreateSchemaStmt(Node *node)
{
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
StringInfoData str = { 0 };
initStringInfo(&str);
AppendCreateSchemaStmt(&str, stmt);
return str.data;
}
char *
DeparseDropSchemaStmt(Node *node)
{
DropStmt *stmt = castNode(DropStmt, node);
StringInfoData str = { 0 };
initStringInfo(&str);
AppendDropSchemaStmt(&str, stmt);
return str.data;
}
char *
DeparseGrantOnSchemaStmt(Node *node)
{
GrantStmt *stmt = castNode(GrantStmt, node);
Assert(stmt->objtype == OBJECT_SCHEMA);
StringInfoData str = { 0 };
initStringInfo(&str);
AppendGrantOnSchemaStmt(&str, stmt);
return str.data;
}
char *
DeparseAlterSchemaOwnerStmt(Node *node)
{
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
StringInfoData str = { 0 };
initStringInfo(&str);
AppendAlterSchemaOwnerStmt(&str, stmt);
return str.data;
}
static void
AppendAlterSchemaOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
{
Assert(stmt->objectType == OBJECT_SCHEMA);
appendStringInfo(buf, "ALTER SCHEMA %s OWNER TO %s;",
quote_identifier(strVal(stmt->object)),
RoleSpecString(stmt->newowner, true));
}
char *
DeparseAlterSchemaRenameStmt(Node *node)
{
RenameStmt *stmt = castNode(RenameStmt, node);
StringInfoData str = { 0 };
initStringInfo(&str);
AppendAlterSchemaRenameStmt(&str, stmt);
return str.data;
}
static void
AppendCreateSchemaStmt(StringInfo buf, CreateSchemaStmt *stmt)
{
appendStringInfoString(buf, "CREATE SCHEMA ");
if (stmt->if_not_exists)
{
appendStringInfoString(buf, "IF NOT EXISTS ");
}
if (stmt->schemaname != NULL)
{
appendStringInfo(buf, "%s ", quote_identifier(stmt->schemaname));
}
else
{
/*
* If the schema name is not provided, the schema will be created
* with the name of the authorizated user.
*/
Assert(stmt->authrole != NULL);
}
if (stmt->authrole != NULL)
{
appendStringInfo(buf, "AUTHORIZATION %s", RoleSpecString(stmt->authrole, true));
}
}
static void
AppendDropSchemaStmt(StringInfo buf, DropStmt *stmt)
{
Assert(stmt->removeType == OBJECT_SCHEMA);
appendStringInfoString(buf, "DROP SCHEMA ");
if (stmt->missing_ok)
{
appendStringInfoString(buf, "IF EXISTS ");
}
String *schemaValue = NULL;
foreach_ptr(schemaValue, stmt->objects)
{
const char *schemaString = quote_identifier(strVal(schemaValue));
appendStringInfo(buf, "%s", schemaString);
if (schemaValue != llast(stmt->objects))
{
appendStringInfoString(buf, ", ");
}
}
if (stmt->behavior == DROP_CASCADE)
{
appendStringInfoString(buf, " CASCADE");
}
else if (stmt->behavior == DROP_RESTRICT)
{
appendStringInfoString(buf, " RESTRICT");
}
}
static void
AppendGrantOnSchemaStmt(StringInfo buf, GrantStmt *stmt)
{
Assert(stmt->objtype == OBJECT_SCHEMA);
AppendGrantSharedPrefix(buf, stmt);
AppendGrantOnSchemaSchemas(buf, stmt);
AppendGrantSharedSuffix(buf, stmt);
}
void
AppendGrantPrivileges(StringInfo buf, GrantStmt *stmt)
{
if (list_length(stmt->privileges) == 0)
{
appendStringInfo(buf, "ALL PRIVILEGES");
}
else
{
ListCell *cell = NULL;
foreach(cell, stmt->privileges)
{
AccessPriv *privilege = (AccessPriv *) lfirst(cell);
appendStringInfoString(buf, privilege->priv_name);
if (cell != list_tail(stmt->privileges))
{
appendStringInfo(buf, ", ");
}
}
}
}
static void
AppendGrantOnSchemaSchemas(StringInfo buf, GrantStmt *stmt)
{
ListCell *cell = NULL;
appendStringInfo(buf, " ON SCHEMA ");
foreach(cell, stmt->objects)
{
char *schema = strVal(lfirst(cell));
appendStringInfoString(buf, quote_identifier(schema));
if (cell != list_tail(stmt->objects))
{
appendStringInfo(buf, ", ");
}
}
}
void
AppendGrantGrantees(StringInfo buf, GrantStmt *stmt)
{
ListCell *cell = NULL;
appendStringInfo(buf, " %s ", stmt->is_grant ? "TO" : "FROM");
foreach(cell, stmt->grantees)
{
RoleSpec *grantee = (RoleSpec *) lfirst(cell);
appendStringInfoString(buf, RoleSpecString(grantee, true));
if (cell != list_tail(stmt->grantees))
{
appendStringInfo(buf, ", ");
}
}
}
static void
AppendAlterSchemaRenameStmt(StringInfo buf, RenameStmt *stmt)
{
Assert(stmt->renameType == OBJECT_SCHEMA);
appendStringInfo(buf, "ALTER SCHEMA %s RENAME TO %s;",
quote_identifier(stmt->subname), quote_identifier(stmt->newname));
}