#include "catalog/pg_collation.h"
 #include "catalog/pg_statistic_ext.h"
 #include "nodes/relation.h"
+#include "postmaster/autovacuum.h"
 #include "statistics/extended_stats_internal.h"
 #include "statistics/statistics.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
+#include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/syscache.h"
 
 typedef struct StatExtEntry
 {
    Oid         statOid;    /* OID of pg_statistic_ext entry */
+   char       *schema;     /* statistics schema */
+   char       *name;       /* statistics name */
    Bitmapset  *columns;    /* attribute numbers covered by the statistics */
    List       *types;      /* 'char' list of enabled statistic kinds */
 } StatExtEntry;
 
 static List *fetch_statentries_for_relation(Relation pg_statext, Oid relid);
 static VacAttrStats **lookup_var_attr_stats(Relation rel, Bitmapset *attrs,
-                     int natts, VacAttrStats **vacattrstats);
+                     int nvacatts, VacAttrStats **vacatts);
 static void statext_store(Relation pg_stext, Oid relid,
              MVNDistinct *ndistinct, MVDependencies *dependencies,
              VacAttrStats **stats);
    Relation    pg_stext;
    ListCell   *lc;
    List       *stats;
+   MemoryContext cxt;
+   MemoryContext oldcxt;
+
+   cxt = AllocSetContextCreate(CurrentMemoryContext, "stats ext",
+                               ALLOCSET_DEFAULT_SIZES);
+   oldcxt = MemoryContextSwitchTo(cxt);
 
    pg_stext = heap_open(StatisticExtRelationId, RowExclusiveLock);
    stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
        VacAttrStats  **stats;
        ListCell       *lc2;
 
-       /* filter only the interesting vacattrstats records */
+       /*
+        * Check if we can build these stats based on the column analyzed.
+        * If not, report this fact (except in autovacuum) and move on.
+        */
        stats = lookup_var_attr_stats(onerel, stat->columns,
                                      natts, vacattrstats);
+       if (!stats && !IsAutoVacuumWorkerProcess())
+       {
+           ereport(WARNING,
+                   (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                    errmsg("extended statistics \"%s.%s\" could not be collected for relation %s.%s",
+                           stat->schema, stat->name,
+                           get_namespace_name(onerel->rd_rel->relnamespace),
+                           RelationGetRelationName(onerel)),
+                    errtable(onerel)));
+           continue;
+       }
 
        /* check allowed number of dimensions */
        Assert(bms_num_members(stat->columns) >= 2 &&
    }
 
    heap_close(pg_stext, RowExclusiveLock);
+
+   MemoryContextSwitchTo(oldcxt);
+   MemoryContextDelete(cxt);
 }
 
 /*
        entry = palloc0(sizeof(StatExtEntry));
        entry->statOid = HeapTupleGetOid(htup);
        staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
+       entry->schema = get_namespace_name(staForm->stanamespace);
+       entry->name = pstrdup(NameStr(staForm->staname));
        for (i = 0; i < staForm->stakeys.dim1; i++)
        {
            entry->columns = bms_add_member(entry->columns,
 }
 
 /*
- * Using 'vacattrstats' of size 'natts' as input data, return a newly built
- * VacAttrStats array which includes only the items corresponding to attributes
- * indicated by 'attrs'.
+ * Using 'vacatts' of size 'nvacatts' as input data, return a newly built
+ * VacAttrStats array which includes only the items corresponding to
+ * attributes indicated by 'stakeys'. If we don't have all of the per column
+ * stats available to compute the extended stats, then we return NULL to indicate
+ * to the caller that the stats should not be built.
  */
 static VacAttrStats **
-lookup_var_attr_stats(Relation rel, Bitmapset *attrs, int natts,
-                     VacAttrStats **vacattrstats)
+lookup_var_attr_stats(Relation rel, Bitmapset *attrs,
+                     int nvacatts, VacAttrStats **vacatts)
 {
    int         i = 0;
    int         x = -1;
    VacAttrStats **stats;
-   Bitmapset  *matched = NULL;
 
    stats = (VacAttrStats **)
        palloc(bms_num_members(attrs) * sizeof(VacAttrStats *));
        int     j;
 
        stats[i] = NULL;
-       for (j = 0; j < natts; j++)
+       for (j = 0; j < nvacatts; j++)
        {
-           if (x == vacattrstats[j]->tupattnum)
+           if (x == vacatts[j]->tupattnum)
            {
-               stats[i] = vacattrstats[j];
+               stats[i] = vacatts[j];
                break;
            }
        }
 
        if (!stats[i])
-           ereport(ERROR,
-                   (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                    errmsg("extended statistics could not be collected for column \"%s\" of relation %s.%s",
-                           NameStr(RelationGetDescr(rel)->attrs[x - 1]->attname),
-                           get_namespace_name(rel->rd_rel->relnamespace),
-                           RelationGetRelationName(rel)),
-                    errhint("Consider ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1",
-                            get_namespace_name(rel->rd_rel->relnamespace),
-                            RelationGetRelationName(rel),
-                            NameStr(RelationGetDescr(rel)->attrs[x - 1]->attname))));
+       {
+           /*
+            * Looks like stats were not gathered for one of the columns
+            * required. We'll be unable to build the extended stats without
+            * this column.
+            */
+           pfree(stats);
+           return NULL;
+       }
 
-       /*
-        * Check that we found a non-dropped column and that the attnum
-        * matches.
-        */
+        /*
+         * Sanity check that the column is not dropped - stats should have
+         * been removed in this case.
+         */
        Assert(!stats[i]->attr->attisdropped);
-       matched = bms_add_member(matched, stats[i]->tupattnum);
 
        i++;
    }
-   if (bms_subset_compare(matched, attrs) != BMS_EQUAL)
-       elog(ERROR, "could not find all attributes in attribute stats array");
-   bms_free(matched);
 
    return stats;
 }