postgresql/src/test/modules/test_ddl_deparse/test_ddl_deparse.c

342 lines
7.9 KiB
C

/*----------------------------------------------------------------------
* test_ddl_deparse.c
* Support functions for the test_ddl_deparse module
*
* Copyright (c) 2014-2024, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/test/modules/test_ddl_deparse/test_ddl_deparse.c
*----------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "nodes/execnodes.h"
#include "tcop/deparse_utility.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(get_command_type);
PG_FUNCTION_INFO_V1(get_command_tag);
PG_FUNCTION_INFO_V1(get_altertable_subcmdinfo);
/*
* Return the textual representation of the struct type used to represent a
* command in struct CollectedCommand format.
*/
Datum
get_command_type(PG_FUNCTION_ARGS)
{
CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
const char *type;
switch (cmd->type)
{
case SCT_Simple:
type = "simple";
break;
case SCT_AlterTable:
type = "alter table";
break;
case SCT_Grant:
type = "grant";
break;
case SCT_AlterOpFamily:
type = "alter operator family";
break;
case SCT_AlterDefaultPrivileges:
type = "alter default privileges";
break;
case SCT_CreateOpClass:
type = "create operator class";
break;
case SCT_AlterTSConfig:
type = "alter text search configuration";
break;
default:
type = "unknown command type";
break;
}
PG_RETURN_TEXT_P(cstring_to_text(type));
}
/*
* Return the command tag corresponding to a parse node contained in a
* CollectedCommand struct.
*/
Datum
get_command_tag(PG_FUNCTION_ARGS)
{
CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
if (!cmd->parsetree)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(cstring_to_text(CreateCommandName(cmd->parsetree)));
}
/*
* Return a text array representation of the subcommands of an ALTER TABLE
* command.
*/
Datum
get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
{
CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
ListCell *cell;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
if (cmd->type != SCT_AlterTable)
elog(ERROR, "command is not ALTER TABLE");
InitMaterializedSRF(fcinfo, 0);
if (cmd->d.alterTable.subcmds == NIL)
elog(ERROR, "empty alter table subcommand list");
foreach(cell, cmd->d.alterTable.subcmds)
{
CollectedATSubcmd *sub = lfirst(cell);
AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree);
const char *strtype = "unrecognized";
Datum values[2];
bool nulls[2];
memset(values, 0, sizeof(values));
memset(nulls, 0, sizeof(nulls));
switch (subcmd->subtype)
{
case AT_AddColumn:
strtype = "ADD COLUMN";
break;
case AT_AddColumnToView:
strtype = "ADD COLUMN TO VIEW";
break;
case AT_ColumnDefault:
strtype = "ALTER COLUMN SET DEFAULT";
break;
case AT_CookedColumnDefault:
strtype = "ALTER COLUMN SET DEFAULT (precooked)";
break;
case AT_DropNotNull:
strtype = "DROP NOT NULL";
break;
case AT_SetNotNull:
strtype = "SET NOT NULL";
break;
case AT_SetAttNotNull:
strtype = "SET ATTNOTNULL";
break;
case AT_SetExpression:
strtype = "SET EXPRESSION";
break;
case AT_DropExpression:
strtype = "DROP EXPRESSION";
break;
case AT_SetStatistics:
strtype = "SET STATS";
break;
case AT_SetOptions:
strtype = "SET OPTIONS";
break;
case AT_ResetOptions:
strtype = "RESET OPTIONS";
break;
case AT_SetStorage:
strtype = "SET STORAGE";
break;
case AT_SetCompression:
strtype = "SET COMPRESSION";
break;
case AT_DropColumn:
strtype = "DROP COLUMN";
break;
case AT_AddIndex:
strtype = "ADD INDEX";
break;
case AT_ReAddIndex:
strtype = "(re) ADD INDEX";
break;
case AT_AddConstraint:
strtype = "ADD CONSTRAINT";
break;
case AT_ReAddConstraint:
strtype = "(re) ADD CONSTRAINT";
break;
case AT_ReAddDomainConstraint:
strtype = "(re) ADD DOMAIN CONSTRAINT";
break;
case AT_AlterConstraint:
strtype = "ALTER CONSTRAINT";
break;
case AT_ValidateConstraint:
strtype = "VALIDATE CONSTRAINT";
break;
case AT_AddIndexConstraint:
strtype = "ADD CONSTRAINT (using index)";
break;
case AT_DropConstraint:
strtype = "DROP CONSTRAINT";
break;
case AT_ReAddComment:
strtype = "(re) ADD COMMENT";
break;
case AT_AlterColumnType:
strtype = "ALTER COLUMN SET TYPE";
break;
case AT_AlterColumnGenericOptions:
strtype = "ALTER COLUMN SET OPTIONS";
break;
case AT_ChangeOwner:
strtype = "CHANGE OWNER";
break;
case AT_ClusterOn:
strtype = "CLUSTER";
break;
case AT_DropCluster:
strtype = "DROP CLUSTER";
break;
case AT_SetLogged:
strtype = "SET LOGGED";
break;
case AT_SetUnLogged:
strtype = "SET UNLOGGED";
break;
case AT_DropOids:
strtype = "DROP OIDS";
break;
case AT_SetAccessMethod:
strtype = "SET ACCESS METHOD";
break;
case AT_SetTableSpace:
strtype = "SET TABLESPACE";
break;
case AT_SetRelOptions:
strtype = "SET RELOPTIONS";
break;
case AT_ResetRelOptions:
strtype = "RESET RELOPTIONS";
break;
case AT_ReplaceRelOptions:
strtype = "REPLACE RELOPTIONS";
break;
case AT_EnableTrig:
strtype = "ENABLE TRIGGER";
break;
case AT_EnableAlwaysTrig:
strtype = "ENABLE TRIGGER (always)";
break;
case AT_EnableReplicaTrig:
strtype = "ENABLE TRIGGER (replica)";
break;
case AT_DisableTrig:
strtype = "DISABLE TRIGGER";
break;
case AT_EnableTrigAll:
strtype = "ENABLE TRIGGER (all)";
break;
case AT_DisableTrigAll:
strtype = "DISABLE TRIGGER (all)";
break;
case AT_EnableTrigUser:
strtype = "ENABLE TRIGGER (user)";
break;
case AT_DisableTrigUser:
strtype = "DISABLE TRIGGER (user)";
break;
case AT_EnableRule:
strtype = "ENABLE RULE";
break;
case AT_EnableAlwaysRule:
strtype = "ENABLE RULE (always)";
break;
case AT_EnableReplicaRule:
strtype = "ENABLE RULE (replica)";
break;
case AT_DisableRule:
strtype = "DISABLE RULE";
break;
case AT_AddInherit:
strtype = "ADD INHERIT";
break;
case AT_DropInherit:
strtype = "DROP INHERIT";
break;
case AT_AddOf:
strtype = "OF";
break;
case AT_DropOf:
strtype = "NOT OF";
break;
case AT_ReplicaIdentity:
strtype = "REPLICA IDENTITY";
break;
case AT_EnableRowSecurity:
strtype = "ENABLE ROW SECURITY";
break;
case AT_DisableRowSecurity:
strtype = "DISABLE ROW SECURITY";
break;
case AT_ForceRowSecurity:
strtype = "FORCE ROW SECURITY";
break;
case AT_NoForceRowSecurity:
strtype = "NO FORCE ROW SECURITY";
break;
case AT_GenericOptions:
strtype = "SET OPTIONS";
break;
case AT_DetachPartition:
strtype = "DETACH PARTITION";
break;
case AT_AttachPartition:
strtype = "ATTACH PARTITION";
break;
case AT_DetachPartitionFinalize:
strtype = "DETACH PARTITION ... FINALIZE";
break;
case AT_SplitPartition:
strtype = "SPLIT PARTITION";
break;
case AT_MergePartitions:
strtype = "MERGE PARTITIONS";
break;
case AT_AddIdentity:
strtype = "ADD IDENTITY";
break;
case AT_SetIdentity:
strtype = "SET IDENTITY";
break;
case AT_DropIdentity:
strtype = "DROP IDENTITY";
break;
case AT_ReAddStatistics:
strtype = "(re) ADD STATS";
break;
}
if (subcmd->recurse)
values[0] = CStringGetTextDatum(psprintf("%s (and recurse)", strtype));
else
values[0] = CStringGetTextDatum(strtype);
if (OidIsValid(sub->address.objectId))
{
char *objdesc;
objdesc = getObjectDescription((const ObjectAddress *) &sub->address, false);
values[1] = CStringGetTextDatum(objdesc);
}
else
nulls[1] = true;
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
}
return (Datum) 0;
}