Commit d99d58cd authored by Alvaro Herrera's avatar Alvaro Herrera

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
parent 2df5d465
...@@ -16680,6 +16680,12 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); ...@@ -16680,6 +16680,12 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>is operator family visible in search path</entry> <entry>is operator family visible in search path</entry>
</row> </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> <row>
<entry><literal><function>pg_table_is_visible(<parameter>table_oid</parameter>)</function></literal> <entry><literal><function>pg_table_is_visible(<parameter>table_oid</parameter>)</function></literal>
</entry> </entry>
...@@ -16738,6 +16744,9 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); ...@@ -16738,6 +16744,9 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
<indexterm> <indexterm>
<primary>pg_opfamily_is_visible</primary> <primary>pg_opfamily_is_visible</primary>
</indexterm> </indexterm>
<indexterm>
<primary>pg_statistic_ext_is_visible</primary>
</indexterm>
<indexterm> <indexterm>
<primary>pg_table_is_visible</primary> <primary>pg_table_is_visible</primary>
</indexterm> </indexterm>
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h" #include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_ts_config.h" #include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h" #include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h" #include "catalog/pg_ts_parser.h"
...@@ -2141,6 +2142,72 @@ get_statistics_oid(List *names, bool missing_ok) ...@@ -2141,6 +2142,72 @@ get_statistics_oid(List *names, bool missing_ok)
return stats_oid; 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 * get_ts_parser_oid - find a TS parser by possibly qualified name
* *
...@@ -4235,6 +4302,17 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS) ...@@ -4235,6 +4302,17 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(ConversionIsVisible(oid)); 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 Datum
pg_ts_parser_is_visible(PG_FUNCTION_ARGS) pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
{ {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_range.h" #include "catalog/pg_range.h"
#include "catalog/pg_statistic.h" #include "catalog/pg_statistic.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_transform.h" #include "catalog/pg_transform.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "miscadmin.h" #include "miscadmin.h"
......
...@@ -622,7 +622,7 @@ static const SchemaQuery Query_for_list_of_statistics = { ...@@ -622,7 +622,7 @@ static const SchemaQuery Query_for_list_of_statistics = {
/* selcondition */ /* selcondition */
NULL, NULL,
/* viscondition */ /* viscondition */
NULL, "pg_catalog.pg_statistic_ext_is_visible(s.oid)",
/* namespace */ /* namespace */
"s.stxnamespace", "s.stxnamespace",
/* result */ /* result */
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201705121 #define CATALOG_VERSION_NO 201705122
#endif #endif
...@@ -92,6 +92,9 @@ extern bool CollationIsVisible(Oid collid); ...@@ -92,6 +92,9 @@ extern bool CollationIsVisible(Oid collid);
extern Oid ConversionGetConid(const char *conname); extern Oid ConversionGetConid(const char *conname);
extern bool ConversionIsVisible(Oid conid); 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 Oid get_ts_parser_oid(List *names, bool missing_ok);
extern bool TSParserIsVisible(Oid prsId); extern bool TSParserIsVisible(Oid prsId);
...@@ -141,7 +144,6 @@ extern Oid get_collation_oid(List *collname, bool missing_ok); ...@@ -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 get_conversion_oid(List *conname, bool missing_ok);
extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding); extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding);
extern Oid get_statistics_oid(List *names, bool missing_ok);
/* initialization & transaction cleanup code */ /* initialization & transaction cleanup code */
extern void InitializeSearchPath(void); extern void InitializeSearchPath(void);
......
...@@ -3181,6 +3181,8 @@ DATA(insert OID = 3829 ( pg_opfamily_is_visible PGNSP PGUID 12 10 0 0 0 f f f f ...@@ -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?"); 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_ )); 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?"); 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_ )); 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?"); 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_ )); 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_ ));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment