Arrange to put TOAST tables belonging to temporary tables into special schemas
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Jul 2007 22:16:18 +0000 (22:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Jul 2007 22:16:18 +0000 (22:16 +0000)
named pg_toast_temp_nnn, alongside the pg_temp_nnn schemas used for the temp
tables themselves.  This allows low-level code such as the relcache to
recognize that these tables are indeed temporary, which enables various
optimizations such as not WAL-logging changes and using local rather than
shared buffers for access.  Aside from obvious performance benefits, this
provides a solution to bug #3483, in which other backends unexpectedly held
open file references to temporary tables.  The scheme preserves the property
that TOAST tables are not in any schema that's normally in the search path,
so they don't conflict with user table names.

initdb forced because of changes in system view definitions.

contrib/oid2name/oid2name.c
src/backend/catalog/catalog.c
src/backend/catalog/namespace.c
src/backend/catalog/system_views.sql
src/backend/catalog/toasting.c
src/backend/storage/lmgr/lmgr.c
src/backend/utils/cache/relcache.c
src/bin/psql/describe.c
src/include/catalog/catversion.h
src/include/catalog/namespace.h
src/test/regress/expected/rules.out

index eb1d9d84fa6e2a1373bfa969a7593a69081ca8f8..5d5cf5733ebee87e1cfe51e3e5142f1f5310f6dc 100644 (file)
@@ -411,7 +411,7 @@ sql_exec_dumpalltables(PGconn *conn, struct options * opts)
                   "    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
        "       LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),"
                         "      pg_catalog.pg_tablespace t "
-                        "WHERE relkind IN ('r'%s) AND "
+                        "WHERE relkind IN ('r'%s%s) AND "
                         "      %s"
                         "              t.oid = CASE"
                         "                      WHEN reltablespace <> 0 THEN reltablespace"
@@ -419,8 +419,9 @@ sql_exec_dumpalltables(PGconn *conn, struct options * opts)
                         "              END "
                         "ORDER BY relname",
                         opts->extended ? addfields : "",
-                        opts->indexes ? ", 'i', 'S', 't'" : "",
-                        opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema') AND");
+                        opts->indexes ? ", 'i', 'S'" : "",
+                        opts->systables ? ", 't'" : "",
+                        opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND");
 
        sql_exec(conn, todo, opts->quiet);
 }
index 50f269712a5a0fbdb6740e0e027038be4f97c6d1..e3bef0f43d7e1f6bbfb1096172365e0d2dee51a4 100644 (file)
@@ -24,6 +24,7 @@
 #include "access/transam.h"
 #include "catalog/catalog.h"
 #include "catalog/indexing.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_auth_members.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_database.h"
@@ -196,15 +197,17 @@ IsSystemNamespace(Oid namespaceId)
 
 /*
  * IsToastNamespace
- *             True iff namespace is pg_toast.
+ *             True iff namespace is pg_toast or my temporary-toast-table namespace.
  *
- * NOTE: the reason this isn't a macro is to avoid having to include
- * catalog/pg_namespace.h in a lot of places.
+ * Note: this will return false for temporary-toast-table namespaces belonging
+ * to other backends.  Those are treated the same as other backends' regular
+ * temp table namespaces, and access is prevented where appropriate.
  */
 bool
 IsToastNamespace(Oid namespaceId)
 {
-       return namespaceId == PG_TOAST_NAMESPACE;
+       return (namespaceId == PG_TOAST_NAMESPACE) ||
+               isTempToastNamespace(namespaceId);
 }
 
 
index 80377ac16a3ff6b4b0541acaf29cc94ea9df05d8..d441d4bc7dc800c4a494ae9d92349927b206554b 100644 (file)
@@ -152,6 +152,9 @@ static List *overrideStack = NIL;
  * in a particular backend session (this happens when a CREATE TEMP TABLE
  * command is first executed). Thereafter it's the OID of the temp namespace.
  *
+ * myTempToastNamespace is the OID of the namespace for my temp tables' toast
+ * tables.  It is set when myTempNamespace is, and is InvalidOid before that.
+ *
  * myTempNamespaceSubID shows whether we've created the TEMP namespace in the
  * current subtransaction.     The flag propagates up the subtransaction tree,
  * so the main transaction will correctly recognize the flag if all
@@ -161,6 +164,8 @@ static List *overrideStack = NIL;
  */
 static Oid     myTempNamespace = InvalidOid;
 
+static Oid     myTempToastNamespace = InvalidOid;
+
 static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId;
 
 /*
@@ -1599,9 +1604,35 @@ isTempNamespace(Oid namespaceId)
        return false;
 }
 
+/*
+ * isTempToastNamespace - is the given namespace my temporary-toast-table
+ *             namespace?
+ */
+bool
+isTempToastNamespace(Oid namespaceId)
+{
+       if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
+               return true;
+       return false;
+}
+
+/*
+ * isTempOrToastNamespace - is the given namespace my temporary-table
+ *             namespace or my temporary-toast-table namespace?
+ */
+bool
+isTempOrToastNamespace(Oid namespaceId)
+{
+       if (OidIsValid(myTempNamespace) &&
+               (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
+               return true;
+       return false;
+}
+
 /*
  * isAnyTempNamespace - is the given namespace a temporary-table namespace
- * (either my own, or another backend's)?
+ * (either my own, or another backend's)?  Temporary-toast-table namespaces
+ * are included, too.
  */
 bool
 isAnyTempNamespace(Oid namespaceId)
@@ -1609,29 +1640,42 @@ isAnyTempNamespace(Oid namespaceId)
        bool            result;
        char       *nspname;
 
-       /* If the namespace name starts with "pg_temp_", say "true" */
+       /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
        nspname = get_namespace_name(namespaceId);
        if (!nspname)
                return false;                   /* no such namespace? */
-       result = (strncmp(nspname, "pg_temp_", 8) == 0);
+       result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
+               (strncmp(nspname, "pg_toast_temp_", 14) == 0);
        pfree(nspname);
        return result;
 }
 
 /*
  * isOtherTempNamespace - is the given namespace some other backend's
- * temporary-table namespace?
+ * temporary-table namespace (including temporary-toast-table namespaces)?
  */
 bool
 isOtherTempNamespace(Oid namespaceId)
 {
        /* If it's my own temp namespace, say "false" */
-       if (isTempNamespace(namespaceId))
+       if (isTempOrToastNamespace(namespaceId))
                return false;
-       /* Else, if the namespace name starts with "pg_temp_", say "true" */
+       /* Else, if it's any temp namespace, say "true" */
        return isAnyTempNamespace(namespaceId);
 }
 
+/*
+ * GetTempToastNamespace - get the OID of my temporary-toast-table namespace,
+ * which must already be assigned.  (This is only used when creating a toast
+ * table for a temp table, so we must have already done InitTempTableNamespace)
+ */
+Oid
+GetTempToastNamespace(void)
+{
+       Assert(OidIsValid(myTempToastNamespace));
+       return myTempToastNamespace;
+}
+
 
 /*
  * GetOverrideSearchPath - fetch current search path definition in form
@@ -2006,6 +2050,7 @@ InitTempTableNamespace(void)
 {
        char            namespaceName[NAMEDATALEN];
        Oid                     namespaceId;
+       Oid                     toastspaceId;
 
        Assert(!OidIsValid(myTempNamespace));
 
@@ -2054,12 +2099,31 @@ InitTempTableNamespace(void)
                RemoveTempRelations(namespaceId);
        }
 
+       /*
+        * If the corresponding temp-table namespace doesn't exist yet, create it.
+        * (We assume there is no need to clean it out if it does exist, since
+        * dropping a parent table should make its toast table go away.)
+        */
+       snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
+                        MyBackendId);
+
+       toastspaceId = GetSysCacheOid(NAMESPACENAME,
+                                                                 CStringGetDatum(namespaceName),
+                                                                 0, 0, 0);
+       if (!OidIsValid(toastspaceId))
+       {
+               toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
+               /* Advance command counter to make namespace visible */
+               CommandCounterIncrement();
+       }
+
        /*
         * Okay, we've prepared the temp namespace ... but it's not committed yet,
         * so all our work could be undone by transaction rollback.  Set flag for
         * AtEOXact_Namespace to know what to do.
         */
        myTempNamespace = namespaceId;
+       myTempToastNamespace = toastspaceId;
 
        /* It should not be done already. */
        AssertState(myTempNamespaceSubID == InvalidSubTransactionId);
@@ -2089,6 +2153,7 @@ AtEOXact_Namespace(bool isCommit)
                else
                {
                        myTempNamespace = InvalidOid;
+                       myTempToastNamespace = InvalidOid;
                        baseSearchPathValid = false;    /* need to rebuild list */
                }
                myTempNamespaceSubID = InvalidSubTransactionId;
@@ -2140,6 +2205,7 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
                        myTempNamespaceSubID = InvalidSubTransactionId;
                        /* TEMP namespace creation failed, so reset state */
                        myTempNamespace = InvalidOid;
+                       myTempToastNamespace = InvalidOid;
                        baseSearchPathValid = false;    /* need to rebuild list */
                }
        }
index d6b4526554054d196f7defc545b7a5544d8a835a..c4080b677effe8753fd1f56e2b714bc286970fcd 100644 (file)
@@ -221,11 +221,13 @@ CREATE VIEW pg_stat_all_tables AS
 
 CREATE VIEW pg_stat_sys_tables AS 
     SELECT * FROM pg_stat_all_tables 
-    WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+          schemaname ~ '^pg_toast';
 
 CREATE VIEW pg_stat_user_tables AS 
     SELECT * FROM pg_stat_all_tables 
-    WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+          schemaname !~ '^pg_toast';
 
 CREATE VIEW pg_statio_all_tables AS 
     SELECT 
@@ -254,11 +256,13 @@ CREATE VIEW pg_statio_all_tables AS
 
 CREATE VIEW pg_statio_sys_tables AS 
     SELECT * FROM pg_statio_all_tables 
-    WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+          schemaname ~ '^pg_toast';
 
 CREATE VIEW pg_statio_user_tables AS 
     SELECT * FROM pg_statio_all_tables 
-    WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+          schemaname !~ '^pg_toast';
 
 CREATE VIEW pg_stat_all_indexes AS 
     SELECT 
@@ -278,11 +282,13 @@ CREATE VIEW pg_stat_all_indexes AS
 
 CREATE VIEW pg_stat_sys_indexes AS 
     SELECT * FROM pg_stat_all_indexes 
-    WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+          schemaname ~ '^pg_toast';
 
 CREATE VIEW pg_stat_user_indexes AS 
     SELECT * FROM pg_stat_all_indexes 
-    WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+          schemaname !~ '^pg_toast';
 
 CREATE VIEW pg_statio_all_indexes AS 
     SELECT 
@@ -302,11 +308,13 @@ CREATE VIEW pg_statio_all_indexes AS
 
 CREATE VIEW pg_statio_sys_indexes AS 
     SELECT * FROM pg_statio_all_indexes 
-    WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+          schemaname ~ '^pg_toast';
 
 CREATE VIEW pg_statio_user_indexes AS 
     SELECT * FROM pg_statio_all_indexes 
-    WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+          schemaname !~ '^pg_toast';
 
 CREATE VIEW pg_statio_all_sequences AS 
     SELECT 
@@ -322,11 +330,13 @@ CREATE VIEW pg_statio_all_sequences AS
 
 CREATE VIEW pg_statio_sys_sequences AS 
     SELECT * FROM pg_statio_all_sequences 
-    WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+          schemaname ~ '^pg_toast';
 
 CREATE VIEW pg_statio_user_sequences AS 
     SELECT * FROM pg_statio_all_sequences 
-    WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+          schemaname !~ '^pg_toast';
 
 CREATE VIEW pg_stat_activity AS 
     SELECT 
index e6a42c712a73aa440a16406374147365f8fff738..54194ebd533689f061b85ff10638f2c528057768 100644 (file)
@@ -21,6 +21,7 @@
 #include "catalog/heap.h"
 #include "catalog/index.h"
 #include "catalog/indexing.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_type.h"
@@ -108,6 +109,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
        Relation        class_rel;
        Oid                     toast_relid;
        Oid                     toast_idxid;
+       Oid                     namespaceid;
        char            toast_relname[NAMEDATALEN];
        char            toast_idxname[NAMEDATALEN];
        IndexInfo  *indexInfo;
@@ -173,16 +175,20 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
        tupdesc->attrs[2]->attstorage = 'p';
 
        /*
-        * Note: the toast relation is placed in the regular pg_toast namespace
-        * even if its master relation is a temp table.  There cannot be any
-        * naming collision, and the toast rel will be destroyed when its master
-        * is, so there's no need to handle the toast rel as temp.
-        *
+        * Toast tables for regular relations go in pg_toast; those for temp
+        * relations go into the per-backend temp-toast-table namespace.
+        */
+       if (rel->rd_istemp)
+               namespaceid = GetTempToastNamespace();
+       else
+               namespaceid = PG_TOAST_NAMESPACE;
+
+       /*
         * XXX would it make sense to apply the master's reloptions to the toast
-        * table?
+        * table?  Or maybe some toast-specific reloptions?
         */
        toast_relid = heap_create_with_catalog(toast_relname,
-                                                                                  PG_TOAST_NAMESPACE,
+                                                                                  namespaceid,
                                                                                   rel->rd_rel->reltablespace,
                                                                                   toastOid,
                                                                                   rel->rd_rel->relowner,
index 98ede00682e130111586c2e52fc4f5479e63d910..671bcd76ebe9b35b552f0ad83c120ec8c9b8e0c0 100644 (file)
@@ -619,7 +619,7 @@ LockTagIsTemp(const LOCKTAG *tag)
                        /* field1 is dboid, field2 is reloid for all of these */
                        if ((Oid) tag->locktag_field1 == InvalidOid)
                                return false;   /* shared, so not temp */
-                       if (isTempNamespace(get_rel_namespace((Oid) tag->locktag_field2)))
+                       if (isTempOrToastNamespace(get_rel_namespace((Oid) tag->locktag_field2)))
                                return true;
                        break;
                case LOCKTAG_TRANSACTION:
index 788361ade6b553330fde5676c720f6be2bf3b087..e8e485c16ea835e33cedf4883d2bf19f5feff2ed 100644 (file)
@@ -838,7 +838,7 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
        relation->rd_isnailed = false;
        relation->rd_createSubid = InvalidSubTransactionId;
        relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
-       relation->rd_istemp = isTempNamespace(relation->rd_rel->relnamespace);
+       relation->rd_istemp = isTempOrToastNamespace(relation->rd_rel->relnamespace);
 
        /*
         * initialize the tuple descriptor (relation->rd_att).
@@ -2315,7 +2315,7 @@ RelationBuildLocalRelation(const char *relname,
        need_eoxact_work = true;
 
        /* is it a temporary relation? */
-       rel->rd_istemp = isTempNamespace(relnamespace);
+       rel->rd_istemp = isTempOrToastNamespace(relnamespace);
 
        /*
         * create a new tuple descriptor from the one passed in.  We do this
index 824b0d62d2d565e933dc51824c0cdfa67827d5d1..682369ebea1fd669a648ed72723289f112af3575 100644 (file)
@@ -1688,9 +1688,12 @@ listTables(const char *tabtypes, const char *pattern, bool verbose)
         * pg_catalog and pg_toast.  (We don't want to hide temp tables though.)
         */
        if (showSystem)
-               appendPQExpBuffer(&buf, "      AND n.nspname = 'pg_catalog'\n");
+               appendPQExpBuffer(&buf,
+                                                 "  AND n.nspname = 'pg_catalog'\n");
        else
-               appendPQExpBuffer(&buf, "      AND n.nspname NOT IN ('pg_catalog', 'pg_toast')\n");
+               appendPQExpBuffer(&buf,
+                                                 "  AND n.nspname <> 'pg_catalog'\n"
+                                                 "  AND n.nspname !~ '^pg_toast'\n");
 
        processSQLNamePattern(pset.db, &buf, pattern, true, false,
                                                  "n.nspname", "c.relname", NULL,
index e32c35c5a88f3e569c24ece2e491e8a88f1bab40..e1e6707adb02d4e499554b42e4de37fed0ed82a1 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200707051
+#define CATALOG_VERSION_NO     200707251
 
 #endif
index 9452e9a3b66582a4a97e0a6d88088c5383edc3a3..7949a7b8f6b2c03bd325a86c0cdf9d94cd8b7558 100644 (file)
@@ -79,8 +79,11 @@ extern char *NameListToString(List *names);
 extern char *NameListToQuotedString(List *names);
 
 extern bool isTempNamespace(Oid namespaceId);
+extern bool isTempToastNamespace(Oid namespaceId);
+extern bool isTempOrToastNamespace(Oid namespaceId);
 extern bool isAnyTempNamespace(Oid namespaceId);
 extern bool isOtherTempNamespace(Oid namespaceId);
+extern Oid     GetTempToastNamespace(void);
 extern void ResetTempTableNamespace(void);
 
 extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context);
index ebdd4bd9c79efb8f2e1a144968e42a127eda84a3..39e27a749241f29766b99f5e9978fab37608d2cd 100644 (file)
@@ -1294,19 +1294,19 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del, pg_stat_get_live_tuples(c.oid) AS n_live_tup, pg_stat_get_dead_tuples(c.oid) AS n_dead_tup, pg_stat_get_last_vacuum_time(c.oid) AS last_vacuum, pg_stat_get_last_autovacuum_time(c.oid) AS last_autovacuum, pg_stat_get_last_analyze_time(c.oid) AS last_analyze, pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
  pg_stat_bgwriter         | SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed, pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req, pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint, pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean, pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean;
  pg_stat_database         | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit, pg_stat_get_db_tuples_returned(d.oid) AS tup_returned, pg_stat_get_db_tuples_fetched(d.oid) AS tup_fetched, pg_stat_get_db_tuples_inserted(d.oid) AS tup_inserted, pg_stat_get_db_tuples_updated(d.oid) AS tup_updated, pg_stat_get_db_tuples_deleted(d.oid) AS tup_deleted FROM pg_database d;
- pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.n_live_tup, pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.n_live_tup, pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE ((pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_stat_all_indexes.schemaname ~ '^pg_toast'::text));
+ pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.n_live_tup, pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_stat_all_tables.schemaname ~ '^pg_toast'::text));
+ pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE ((pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_stat_all_indexes.schemaname !~ '^pg_toast'::text));
+ pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.n_live_tup, pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_stat_all_tables.schemaname !~ '^pg_toast'::text));
  pg_statio_all_indexes    | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
  pg_statio_all_sequences  | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
  pg_statio_all_tables     | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
- pg_statio_sys_indexes    | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_statio_sys_sequences  | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_statio_sys_tables     | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_statio_user_indexes   | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_statio_user_tables    | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_statio_sys_indexes    | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_statio_all_indexes.schemaname ~ '^pg_toast'::text));
+ pg_statio_sys_sequences  | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_statio_all_sequences.schemaname ~ '^pg_toast'::text));
+ pg_statio_sys_tables     | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_statio_all_tables.schemaname ~ '^pg_toast'::text));
+ pg_statio_user_indexes   | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_indexes.schemaname !~ '^pg_toast'::text));
+ pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_sequences.schemaname !~ '^pg_toast'::text));
+ pg_statio_user_tables    | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_tables.schemaname !~ '^pg_toast'::text));
  pg_stats                 | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
  pg_tables                | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS tablespace, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
  pg_timezone_abbrevs      | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);