Drop ruleutils copied for statistics

pull/5636/head
Onur Tirtir 2022-01-20 10:43:15 +03:00
parent 7b59295af2
commit 181111b84f
6 changed files with 15 additions and 493 deletions

View File

@ -40,6 +40,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/fmgrprotos.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/ruleutils.h" #include "utils/ruleutils.h"
@ -447,8 +448,20 @@ GetExplicitStatisticsCommandList(Oid relationId)
foreach_oid(statisticsId, statisticsIdList) foreach_oid(statisticsId, statisticsIdList)
{ {
/* we need create commands for already created stats before distribution */ /* we need create commands for already created stats before distribution */
char *createStatisticsCommand = pg_get_statisticsobj_worker_compat(statisticsId, Datum commandText = DirectFunctionCall1(pg_get_statisticsobjdef,
false, false); ObjectIdGetDatum(statisticsId));
/*
* pg_get_statisticsobjdef doesn't throw an error if there is no such
* statistics object, be on the safe side.
*/
if (DatumGetPointer(commandText) == NULL)
{
ereport(ERROR, (errmsg("statistics with oid %u does not exist",
statisticsId)));
}
char *createStatisticsCommand = TextDatumGetCString(commandText);
explicitStatisticsCommandList = explicitStatisticsCommandList =
lappend(explicitStatisticsCommandList, lappend(explicitStatisticsCommandList,

View File

@ -427,7 +427,6 @@ static void get_from_clause_coldeflist(RangeTblFunction *rtfunc,
deparse_context *context); deparse_context *context);
static void get_tablesample_def(TableSampleClause *tablesample, static void get_tablesample_def(TableSampleClause *tablesample,
deparse_context *context); deparse_context *context);
char *pg_get_statisticsobj_worker(Oid statextid, bool missing_ok);
static void get_opclass_name(Oid opclass, Oid actual_datatype, static void get_opclass_name(Oid opclass, Oid actual_datatype,
StringInfo buf); StringInfo buf);
static Node *processIndirection(Node *node, deparse_context *context); static Node *processIndirection(Node *node, deparse_context *context);
@ -7516,127 +7515,6 @@ get_tablesample_def(TableSampleClause *tablesample, deparse_context *context)
} }
char *
pg_get_statisticsobj_worker(Oid statextid, bool missing_ok)
{
StringInfoData buf;
int colno;
bool isnull;
int i;
HeapTuple statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid));
if (!HeapTupleIsValid(statexttup))
{
if (missing_ok)
{
return NULL;
}
elog(ERROR, "cache lookup failed for statistics object %u", statextid);
}
Form_pg_statistic_ext statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup);
initStringInfo(&buf);
char *nsp = get_namespace_name(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
NameStr(statextrec->stxname)));
/*
* Decode the stxkind column so that we know which stats types to print.
*/
Datum datum = SysCacheGetAttr(STATEXTOID, statexttup,
Anum_pg_statistic_ext_stxkind, &isnull);
Assert(!isnull);
ArrayType *arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
{
elog(ERROR, "stxkind is not a 1-D char array");
}
char *enabled = (char *) ARR_DATA_PTR(arr);
bool ndistinct_enabled = false;
bool dependencies_enabled = false;
bool mcv_enabled = false;
for (i = 0; i < ARR_DIMS(arr)[0]; i++)
{
if (enabled[i] == STATS_EXT_NDISTINCT)
{
ndistinct_enabled = true;
}
if (enabled[i] == STATS_EXT_DEPENDENCIES)
{
dependencies_enabled = true;
}
if (enabled[i] == STATS_EXT_MCV)
{
mcv_enabled = true;
}
}
/*
* If any option is disabled, then we'll need to append the types clause
* to show which options are enabled. We omit the types clause on purpose
* when all options are enabled, so a pg_dump/pg_restore will create all
* statistics types on a newer postgres version, if the statistics had all
* options enabled on the original version.
*/
if (!ndistinct_enabled || !dependencies_enabled || !mcv_enabled)
{
bool gotone = false;
appendStringInfoString(&buf, " (");
if (ndistinct_enabled)
{
appendStringInfoString(&buf, "ndistinct");
gotone = true;
}
if (dependencies_enabled)
{
appendStringInfo(&buf, "%sdependencies", gotone ? ", " : "");
gotone = true;
}
if (mcv_enabled)
{
appendStringInfo(&buf, "%smcv", gotone ? ", " : "");
}
appendStringInfoChar(&buf, ')');
}
appendStringInfoString(&buf, " ON ");
for (colno = 0; colno < statextrec->stxkeys.dim1; colno++)
{
AttrNumber attnum = statextrec->stxkeys.values[colno];
if (colno > 0)
{
appendStringInfoString(&buf, ", ");
}
char *attname = get_attname(statextrec->stxrelid, attnum, false);
appendStringInfoString(&buf, quote_identifier(attname));
}
appendStringInfo(&buf, " FROM %s",
generate_relation_name(statextrec->stxrelid, NIL));
ReleaseSysCache(statexttup);
return buf.data;
}
/* /*
* get_opclass_name - fetch name of an index operator class * get_opclass_name - fetch name of an index operator class
* *

View File

@ -432,7 +432,6 @@ static void get_from_clause_coldeflist(RangeTblFunction *rtfunc,
deparse_context *context); deparse_context *context);
static void get_tablesample_def(TableSampleClause *tablesample, static void get_tablesample_def(TableSampleClause *tablesample,
deparse_context *context); deparse_context *context);
char *pg_get_statisticsobj_worker(Oid statextid, bool missing_ok);
static void get_opclass_name(Oid opclass, Oid actual_datatype, static void get_opclass_name(Oid opclass, Oid actual_datatype,
StringInfo buf); StringInfo buf);
static Node *processIndirection(Node *node, deparse_context *context); static Node *processIndirection(Node *node, deparse_context *context);
@ -7574,127 +7573,6 @@ get_tablesample_def(TableSampleClause *tablesample, deparse_context *context)
} }
char *
pg_get_statisticsobj_worker(Oid statextid, bool missing_ok)
{
StringInfoData buf;
int colno;
bool isnull;
int i;
HeapTuple statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid));
if (!HeapTupleIsValid(statexttup))
{
if (missing_ok)
{
return NULL;
}
elog(ERROR, "cache lookup failed for statistics object %u", statextid);
}
Form_pg_statistic_ext statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup);
initStringInfo(&buf);
char *nsp = get_namespace_name(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
NameStr(statextrec->stxname)));
/*
* Decode the stxkind column so that we know which stats types to print.
*/
Datum datum = SysCacheGetAttr(STATEXTOID, statexttup,
Anum_pg_statistic_ext_stxkind, &isnull);
Assert(!isnull);
ArrayType *arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
{
elog(ERROR, "stxkind is not a 1-D char array");
}
char *enabled = (char *) ARR_DATA_PTR(arr);
bool ndistinct_enabled = false;
bool dependencies_enabled = false;
bool mcv_enabled = false;
for (i = 0; i < ARR_DIMS(arr)[0]; i++)
{
if (enabled[i] == STATS_EXT_NDISTINCT)
{
ndistinct_enabled = true;
}
if (enabled[i] == STATS_EXT_DEPENDENCIES)
{
dependencies_enabled = true;
}
if (enabled[i] == STATS_EXT_MCV)
{
mcv_enabled = true;
}
}
/*
* If any option is disabled, then we'll need to append the types clause
* to show which options are enabled. We omit the types clause on purpose
* when all options are enabled, so a pg_dump/pg_restore will create all
* statistics types on a newer postgres version, if the statistics had all
* options enabled on the original version.
*/
if (!ndistinct_enabled || !dependencies_enabled || !mcv_enabled)
{
bool gotone = false;
appendStringInfoString(&buf, " (");
if (ndistinct_enabled)
{
appendStringInfoString(&buf, "ndistinct");
gotone = true;
}
if (dependencies_enabled)
{
appendStringInfo(&buf, "%sdependencies", gotone ? ", " : "");
gotone = true;
}
if (mcv_enabled)
{
appendStringInfo(&buf, "%smcv", gotone ? ", " : "");
}
appendStringInfoChar(&buf, ')');
}
appendStringInfoString(&buf, " ON ");
for (colno = 0; colno < statextrec->stxkeys.dim1; colno++)
{
AttrNumber attnum = statextrec->stxkeys.values[colno];
if (colno > 0)
{
appendStringInfoString(&buf, ", ");
}
char *attname = get_attname(statextrec->stxrelid, attnum, false);
appendStringInfoString(&buf, quote_identifier(attname));
}
appendStringInfo(&buf, " FROM %s",
generate_relation_name(statextrec->stxrelid, NIL));
ReleaseSysCache(statexttup);
return buf.data;
}
/* /*
* get_opclass_name - fetch name of an index operator class * get_opclass_name - fetch name of an index operator class
* *

View File

@ -320,9 +320,6 @@ typedef struct
* as a parameter, and append their text output to its contents. * as a parameter, and append their text output to its contents.
* ---------- * ----------
*/ */
static char *deparse_expression_pretty(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit,
int prettyFlags, int startIndent);
static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces, static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
Bitmapset *rels_used); Bitmapset *rels_used);
static void set_deparse_for_query(deparse_namespace *dpns, Query *query, static void set_deparse_for_query(deparse_namespace *dpns, Query *query,
@ -440,8 +437,6 @@ static void get_from_clause_coldeflist(RangeTblFunction *rtfunc,
deparse_context *context); deparse_context *context);
static void get_tablesample_def(TableSampleClause *tablesample, static void get_tablesample_def(TableSampleClause *tablesample,
deparse_context *context); deparse_context *context);
char *pg_get_statisticsobj_worker(Oid statextid, bool columns_only,
bool missing_ok);
static void get_opclass_name(Oid opclass, Oid actual_datatype, static void get_opclass_name(Oid opclass, Oid actual_datatype,
StringInfo buf); StringInfo buf);
static Node *processIndirection(Node *node, deparse_context *context); static Node *processIndirection(Node *node, deparse_context *context);
@ -648,51 +643,6 @@ pg_get_rule_expr(Node *expression)
} }
/* ----------
* deparse_expression_pretty - General utility for deparsing expressions
*
* expr is the node tree to be deparsed. It must be a transformed expression
* tree (ie, not the raw output of gram.y).
*
* dpcontext is a list of deparse_namespace nodes representing the context
* for interpreting Vars in the node tree. It can be NIL if no Vars are
* expected.
*
* forceprefix is true to force all Vars to be prefixed with their table names.
*
* showimplicit is true to force all implicit casts to be shown explicitly.
*
* Tries to pretty up the output according to prettyFlags and startIndent.
*
* The result is a palloc'd string.
* ----------
*/
static char *
deparse_expression_pretty(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit,
int prettyFlags, int startIndent)
{
StringInfoData buf;
deparse_context context;
initStringInfo(&buf);
context.buf = &buf;
context.namespaces = dpcontext;
context.windowClause = NIL;
context.windowTList = NIL;
context.varprefix = forceprefix;
context.prettyFlags = prettyFlags;
context.wrapColumn = WRAP_COLUMN_DEFAULT;
context.indentLevel = startIndent;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
get_rule_expr(expr, &context, showimplicit);
return buf.data;
}
/* /*
* set_rtable_names: select RTE aliases to be used in printing a query * set_rtable_names: select RTE aliases to be used in printing a query
* *
@ -8130,195 +8080,6 @@ get_tablesample_def(TableSampleClause *tablesample, deparse_context *context)
} }
char *
pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
{
StringInfoData buf;
int colno;
char *nsp;
ArrayType *arr;
char *enabled;
Datum datum;
bool isnull;
bool ndistinct_enabled;
bool dependencies_enabled;
bool mcv_enabled;
int i;
List *context;
ListCell *lc;
List *exprs = NIL;
bool has_exprs;
int ncolumns;
HeapTuple statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid));
if (!HeapTupleIsValid(statexttup))
{
if (missing_ok)
{
return NULL;
}
elog(ERROR, "cache lookup failed for statistics object %u", statextid);
}
/* has the statistics expressions? */
has_exprs = !heap_attisnull(statexttup, Anum_pg_statistic_ext_stxexprs, NULL);
Form_pg_statistic_ext statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup);
/*
* Get the statistics expressions, if any. (NOTE: we do not use the
* relcache versions of the expressions, because we want to display
* non-const-folded expressions.)
*/
if (has_exprs)
{
Datum exprsDatum;
bool isNull;
char *exprsString;
exprsDatum = SysCacheGetAttr(STATEXTOID, statexttup,
Anum_pg_statistic_ext_stxexprs, &isNull);
Assert(!isNull);
exprsString = TextDatumGetCString(exprsDatum);
exprs = (List *) stringToNode(exprsString);
pfree(exprsString);
}
else
{
exprs = NIL;
}
/* count the number of columns (attributes and expressions) */
ncolumns = statextrec->stxkeys.dim1 + list_length(exprs);
initStringInfo(&buf);
if (!columns_only)
{
nsp = get_namespace_name(statextrec->stxnamespace);
appendStringInfo(&buf, "CREATE STATISTICS %s",
quote_qualified_identifier(nsp,
NameStr(statextrec->stxname)));
/*
* Decode the stxkind column so that we know which stats types to
* print.
*/
datum = SysCacheGetAttr(STATEXTOID, statexttup,
Anum_pg_statistic_ext_stxkind, &isnull);
Assert(!isnull);
arr = DatumGetArrayTypeP(datum);
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
elog(ERROR, "stxkind is not a 1-D char array");
enabled = (char *) ARR_DATA_PTR(arr);
ndistinct_enabled = false;
dependencies_enabled = false;
mcv_enabled = false;
for (i = 0; i < ARR_DIMS(arr)[0]; i++)
{
if (enabled[i] == STATS_EXT_NDISTINCT)
ndistinct_enabled = true;
else if (enabled[i] == STATS_EXT_DEPENDENCIES)
dependencies_enabled = true;
else if (enabled[i] == STATS_EXT_MCV)
mcv_enabled = true;
/* ignore STATS_EXT_EXPRESSIONS (it's built automatically) */
}
/*
* If any option is disabled, then we'll need to append the types
* clause to show which options are enabled. We omit the types clause
* on purpose when all options are enabled, so a pg_dump/pg_restore
* will create all statistics types on a newer postgres version, if
* the statistics had all options enabled on the original version.
*
* But if the statistics is defined on just a single column, it has to
* be an expression statistics. In that case we don't need to specify
* kinds.
*/
if ((!ndistinct_enabled || !dependencies_enabled || !mcv_enabled) &&
(ncolumns > 1))
{
bool gotone = false;
appendStringInfoString(&buf, " (");
if (ndistinct_enabled)
{
appendStringInfoString(&buf, "ndistinct");
gotone = true;
}
if (dependencies_enabled)
{
appendStringInfo(&buf, "%sdependencies", gotone ? ", " : "");
gotone = true;
}
if (mcv_enabled)
appendStringInfo(&buf, "%smcv", gotone ? ", " : "");
appendStringInfoChar(&buf, ')');
}
appendStringInfoString(&buf, " ON ");
}
/* decode simple column references */
for (colno = 0; colno < statextrec->stxkeys.dim1; colno++)
{
AttrNumber attnum = statextrec->stxkeys.values[colno];
if (colno > 0)
{
appendStringInfoString(&buf, ", ");
}
char *attname = get_attname(statextrec->stxrelid, attnum, false);
appendStringInfoString(&buf, quote_identifier(attname));
}
context = deparse_context_for(get_relation_name(statextrec->stxrelid),
statextrec->stxrelid);
foreach(lc, exprs)
{
Node *expr = (Node *) lfirst(lc);
char *str;
int prettyFlags = PRETTYFLAG_INDENT;
str = deparse_expression_pretty(expr, context, false, false,
prettyFlags, 0);
if (colno > 0)
appendStringInfoString(&buf, ", ");
/* Need parens if it's not a bare function call */
if (looks_like_function(expr))
appendStringInfoString(&buf, str);
else
appendStringInfo(&buf, "(%s)", str);
colno++;
}
if (!columns_only)
appendStringInfo(&buf, " FROM %s",
generate_relation_name(statextrec->stxrelid, NIL));
ReleaseSysCache(statexttup);
return buf.data;
}
/* /*
* get_opclass_name - fetch name of an index operator class * get_opclass_name - fetch name of an index operator class
* *

View File

@ -54,12 +54,6 @@ bool get_merged_argument_list(CallStmt *stmt, List **mergedNamedArgList,
char * pg_get_rule_expr(Node *expression); char * pg_get_rule_expr(Node *expression);
extern void deparse_shard_query(Query *query, Oid distrelid, int64 shardid, extern void deparse_shard_query(Query *query, Oid distrelid, int64 shardid,
StringInfo buffer); StringInfo buffer);
#if PG_VERSION_NUM >= PG_VERSION_14
extern char * pg_get_statisticsobj_worker(Oid statextid, bool columns_only,
bool missing_ok);
#else
extern char * pg_get_statisticsobj_worker(Oid statextid, bool missing_ok);
#endif
extern char * generate_relation_name(Oid relid, List *namespaces); extern char * generate_relation_name(Oid relid, List *namespaces);
extern char * generate_qualified_relation_name(Oid relid); extern char * generate_qualified_relation_name(Oid relid);
extern char * generate_operator_name(Oid operid, Oid arg1, Oid arg2); extern char * generate_operator_name(Oid operid, Oid arg1, Oid arg2);

View File

@ -35,7 +35,6 @@
#define RelationGetPartitionDesc_compat(a, b) RelationGetPartitionDesc(a, b) #define RelationGetPartitionDesc_compat(a, b) RelationGetPartitionDesc(a, b)
#define make_simple_restrictinfo_compat(a, b) make_simple_restrictinfo(a, b) #define make_simple_restrictinfo_compat(a, b) make_simple_restrictinfo(a, b)
#define pull_varnos_compat(a, b) pull_varnos(a, b) #define pull_varnos_compat(a, b) pull_varnos(a, b)
#define pg_get_statisticsobj_worker_compat(a, b, c) pg_get_statisticsobj_worker(a, b, c)
#else #else
#define AlterTableStmtObjType_compat(a) ((a)->relkind) #define AlterTableStmtObjType_compat(a) ((a)->relkind)
#define F_NEXTVAL F_NEXTVAL_OID #define F_NEXTVAL F_NEXTVAL_OID
@ -68,7 +67,6 @@
#define PQ_LARGE_MESSAGE_LIMIT 0 #define PQ_LARGE_MESSAGE_LIMIT 0
#define make_simple_restrictinfo_compat(a, b) make_simple_restrictinfo(b) #define make_simple_restrictinfo_compat(a, b) make_simple_restrictinfo(b)
#define pull_varnos_compat(a, b) pull_varnos(b) #define pull_varnos_compat(a, b) pull_varnos(b)
#define pg_get_statisticsobj_worker_compat(a, b, c) pg_get_statisticsobj_worker(a, c)
#endif #endif
#if PG_VERSION_NUM >= PG_VERSION_13 #if PG_VERSION_NUM >= PG_VERSION_13