aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/namespace.c78
-rw-r--r--src/backend/utils/cache/lsyscache.c1
-rw-r--r--src/bin/psql/tab-complete.c2
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/namespace.h4
-rw-r--r--src/include/catalog/pg_proc.h2
6 files changed, 86 insertions, 3 deletions
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index e521bd908a2..5b339222af1 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -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"
@@ -2142,6 +2143,72 @@ get_statistics_oid(List *names, bool missing_ok)
}
/*
+ * 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
*
* If not found, returns InvalidOid if missing_ok, else throws error
@@ -4236,6 +4303,17 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS)
}
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)
{
Oid oid = PG_GETARG_OID(0);
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 236d876b1c6..720e5402768 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -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"
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 09fb30f270c..ae3730257d1 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -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 */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 85ee2f6bdee..8e5b95a5eea 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201705121
+#define CATALOG_VERSION_NO 201705122
#endif
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 35e0e2b089b..959ee4c50e9 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -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);
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 77d8ed51849..8d84d9a8908 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -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_ ));