Complete tab completion for DROP STATISTICS

Tab-completing DROP STATISTICS would only work if you started writing
the schema name containing the statistics object, because the visibility
clause was missing.  To add it, we need to add SQL-callable support for
testing visibility of a statistics object, like all other object types
already have.

Discussion: https://postgr.es/m/22676.1494557205@sss.pgh.pa.us
This commit is contained in:
Alvaro Herrera 2017-05-13 01:05:48 -03:00
parent 2df5d46555
commit d99d58cdc8
7 changed files with 95 additions and 3 deletions

View File

@ -16680,6 +16680,12 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
<entry><type>boolean</type></entry>
<entry>is operator family visible in search path</entry>
</row>
<row>
<entry><literal><function>pg_statistic_ext_is_visible(<parameter>stat_oid</parameter>)</function></literal>
</entry>
<entry><type>boolean</type></entry>
<entry>is statistics object visible in search path</entry>
</row>
<row>
<entry><literal><function>pg_table_is_visible(<parameter>table_oid</parameter>)</function></literal>
</entry>
@ -16738,6 +16744,9 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
<indexterm>
<primary>pg_opfamily_is_visible</primary>
</indexterm>
<indexterm>
<primary>pg_statistic_ext_is_visible</primary>
</indexterm>
<indexterm>
<primary>pg_table_is_visible</primary>
</indexterm>

View File

@ -34,6 +34,7 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
@ -2141,6 +2142,72 @@ get_statistics_oid(List *names, bool missing_ok)
return stats_oid;
}
/*
* StatisticsObjIsVisible
* Determine whether a statistics object (identified by OID) is visible in
* the current search path. Visible means "would be found by searching
* for the unqualified statistics object name".
*/
bool
StatisticsObjIsVisible(Oid relid)
{
HeapTuple stxtup;
Form_pg_statistic_ext stxform;
Oid stxnamespace;
bool visible;
stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(stxtup))
elog(ERROR, "cache lookup failed for statistics object %u", relid);
stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
recomputeNamespacePath();
/*
* Quick check: if it ain't in the path at all, it ain't visible. Items in
* the system namespace are surely in the path and so we needn't even do
* list_member_oid() for them.
*/
stxnamespace = stxform->stxnamespace;
if (stxnamespace != PG_CATALOG_NAMESPACE &&
!list_member_oid(activeSearchPath, stxnamespace))
visible = false;
else
{
/*
* If it is in the path, it might still not be visible; it could be
* hidden by another statistics object of the same name earlier in the
* path. So we must do a slow check for conflicting objects.
*/
char *stxname = NameStr(stxform->stxname);
ListCell *l;
visible = false;
foreach(l, activeSearchPath)
{
Oid namespaceId = lfirst_oid(l);
if (namespaceId == stxnamespace)
{
/* Found it first in path */
visible = true;
break;
}
if (SearchSysCacheExists2(STATEXTNAMENSP,
PointerGetDatum(stxname),
ObjectIdGetDatum(namespaceId)))
{
/* Found something else first in path */
break;
}
}
}
ReleaseSysCache(stxtup);
return visible;
}
/*
* get_ts_parser_oid - find a TS parser by possibly qualified name
*
@ -4235,6 +4302,17 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(ConversionIsVisible(oid));
}
Datum
pg_statistic_ext_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
if (!SearchSysCacheExists1(STATEXTOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
PG_RETURN_BOOL(StatisticsObjIsVisible(oid));
}
Datum
pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
{

View File

@ -32,6 +32,7 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_range.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_transform.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"

View File

@ -622,7 +622,7 @@ static const SchemaQuery Query_for_list_of_statistics = {
/* selcondition */
NULL,
/* viscondition */
NULL,
"pg_catalog.pg_statistic_ext_is_visible(s.oid)",
/* namespace */
"s.stxnamespace",
/* result */

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201705121
#define CATALOG_VERSION_NO 201705122
#endif

View File

@ -92,6 +92,9 @@ extern bool CollationIsVisible(Oid collid);
extern Oid ConversionGetConid(const char *conname);
extern bool ConversionIsVisible(Oid conid);
extern Oid get_statistics_oid(List *names, bool missing_ok);
extern bool StatisticsObjIsVisible(Oid stxid);
extern Oid get_ts_parser_oid(List *names, bool missing_ok);
extern bool TSParserIsVisible(Oid prsId);
@ -141,7 +144,6 @@ extern Oid get_collation_oid(List *collname, bool missing_ok);
extern Oid get_conversion_oid(List *conname, bool missing_ok);
extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding);
extern Oid get_statistics_oid(List *names, bool missing_ok);
/* initialization & transaction cleanup code */
extern void InitializeSearchPath(void);

View File

@ -3181,6 +3181,8 @@ DATA(insert OID = 3829 ( pg_opfamily_is_visible PGNSP PGUID 12 10 0 0 0 f f f f
DESCR("is opfamily visible in search path?");
DATA(insert OID = 2093 ( pg_conversion_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ pg_conversion_is_visible _null_ _null_ _null_ ));
DESCR("is conversion visible in search path?");
DATA(insert OID = 3403 ( pg_statistic_ext_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ pg_statistic_ext_is_visible _null_ _null_ _null_ ));
DESCR("is statistics object visible in search path?");
DATA(insert OID = 3756 ( pg_ts_parser_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ pg_ts_parser_is_visible _null_ _null_ _null_ ));
DESCR("is text search parser visible in search path?");
DATA(insert OID = 3757 ( pg_ts_dict_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ pg_ts_dict_is_visible _null_ _null_ _null_ ));