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

271 lines
6.1 KiB
C

/*-------------------------------------------------------------------------
*
* deparse_statistics_stmts.c
* All routines to deparse statistics statements.
* This file contains all entry points specific for statistics statement deparsing
* as well as functions that are currently only used for deparsing of the statistics
* statements.
*
* Copyright (c) Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/namespace.h"
#include "lib/stringinfo.h"
#include "nodes/nodes.h"
#include "utils/builtins.h"
#include "pg_version_constants.h"
#include "distributed/citus_ruleutils.h"
#include "distributed/deparser.h"
#include "distributed/listutils.h"
#include "distributed/relay_utility.h"
static void AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt);
static void AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists);
static void AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt);
static void AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
static void AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt);
static void AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt);
static void AppendStatTypes(StringInfo buf, CreateStatsStmt *stmt);
static void AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt);
static void AppendTableName(StringInfo buf, CreateStatsStmt *stmt);
char *
DeparseCreateStatisticsStmt(Node *node)
{
CreateStatsStmt *stmt = castNode(CreateStatsStmt, node);
StringInfoData str;
initStringInfo(&str);
AppendCreateStatisticsStmt(&str, stmt);
return str.data;
}
char *
DeparseDropStatisticsStmt(List *nameList, bool ifExists)
{
StringInfoData str;
initStringInfo(&str);
AppendDropStatisticsStmt(&str, nameList, ifExists);
return str.data;
}
char *
DeparseAlterStatisticsRenameStmt(Node *node)
{
RenameStmt *stmt = castNode(RenameStmt, node);
StringInfoData str;
initStringInfo(&str);
AppendAlterStatisticsRenameStmt(&str, stmt);
return str.data;
}
char *
DeparseAlterStatisticsSchemaStmt(Node *node)
{
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
StringInfoData str;
initStringInfo(&str);
AppendAlterStatisticsSchemaStmt(&str, stmt);
return str.data;
}
char *
DeparseAlterStatisticsStmt(Node *node)
{
AlterStatsStmt *stmt = castNode(AlterStatsStmt, node);
StringInfoData str;
initStringInfo(&str);
AppendAlterStatisticsStmt(&str, stmt);
return str.data;
}
char *
DeparseAlterStatisticsOwnerStmt(Node *node)
{
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
Assert(stmt->objectType == OBJECT_STATISTIC_EXT);
StringInfoData str;
initStringInfo(&str);
AppendAlterStatisticsOwnerStmt(&str, stmt);
return str.data;
}
static void
AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt)
{
appendStringInfoString(buf, "CREATE STATISTICS ");
if (stmt->if_not_exists)
{
appendStringInfoString(buf, "IF NOT EXISTS ");
}
AppendStatisticsName(buf, stmt);
AppendStatTypes(buf, stmt);
appendStringInfoString(buf, " ON ");
AppendColumnNames(buf, stmt);
appendStringInfoString(buf, " FROM ");
AppendTableName(buf, stmt);
}
static void
AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists)
{
appendStringInfoString(buf, "DROP STATISTICS ");
if (ifExists)
{
appendStringInfoString(buf, "IF EXISTS ");
}
appendStringInfo(buf, "%s", NameListToQuotedString(nameList));
}
static void
AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt)
{
appendStringInfo(buf, "ALTER STATISTICS %s RENAME TO %s",
NameListToQuotedString((List *) stmt->object), quote_identifier(
stmt->newname));
}
static void
AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
{
appendStringInfo(buf, "ALTER STATISTICS %s SET SCHEMA %s",
NameListToQuotedString((List *) stmt->object), quote_identifier(
stmt->newschema));
}
static void
AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
{
appendStringInfo(buf, "ALTER STATISTICS %s SET STATISTICS %d", NameListToQuotedString(
stmt->defnames), stmt->stxstattarget);
}
static void
AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
{
List *names = (List *) stmt->object;
appendStringInfo(buf, "ALTER STATISTICS %s OWNER TO %s",
NameListToQuotedString(names),
RoleSpecString(stmt->newowner, true));
}
static void
AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt)
{
String *schemaNameVal = (String *) linitial(stmt->defnames);
const char *schemaName = quote_identifier(strVal(schemaNameVal));
String *statNameVal = (String *) lsecond(stmt->defnames);
const char *statName = quote_identifier(strVal(statNameVal));
appendStringInfo(buf, "%s.%s", schemaName, statName);
}
static void
AppendStatTypes(StringInfo buf, CreateStatsStmt *stmt)
{
if (list_length(stmt->stat_types) == 0)
{
return;
}
appendStringInfoString(buf, " (");
String *statType = NULL;
foreach_ptr(statType, stmt->stat_types)
{
appendStringInfoString(buf, strVal(statType));
if (statType != llast(stmt->stat_types))
{
appendStringInfoString(buf, ", ");
}
}
appendStringInfoString(buf, ")");
}
static void
AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt)
{
StatsElem *column = NULL;
foreach_ptr(column, stmt->exprs)
{
if (!column->name)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg(
"only simple column references are allowed in CREATE STATISTICS")));
}
const char *columnName = quote_identifier(column->name);
appendStringInfoString(buf, columnName);
if (column != llast(stmt->exprs))
{
appendStringInfoString(buf, ", ");
}
}
}
static void
AppendTableName(StringInfo buf, CreateStatsStmt *stmt)
{
/* statistics' can be created with only one relation */
Assert(list_length(stmt->relations) == 1);
RangeVar *relation = (RangeVar *) linitial(stmt->relations);
char *relationName = relation->relname;
char *schemaName = relation->schemaname;
appendStringInfoString(buf, quote_qualified_identifier(schemaName, relationName));
}