*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.122 2008/06/08 22:00:47 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.123 2008/07/01 10:33:09 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
    Form_pg_attribute attr = onerel->rd_att->attrs[attnum - 1];
    HeapTuple   typtuple;
    VacAttrStats *stats;
+   int         i;
    bool        ok;
 
    /* Never analyze dropped columns */
    stats->anl_context = anl_context;
    stats->tupattnum = attnum;
 
+   /*
+    * The fields describing the stats->stavalues[n] element types default
+    * to the type of the field being analyzed, but the type-specific
+    * typanalyze function can change them if it wants to store something
+    * else.
+    */
+   for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
+   {
+       stats->statypid[i] = stats->attr->atttypid;
+       stats->statyplen[i] = stats->attrtype->typlen;
+       stats->statypbyval[i] = stats->attrtype->typbyval;
+       stats->statypalign[i] = stats->attrtype->typalign;
+   }
+
    /*
     * Call the type-specific typanalyze function.  If none is specified, use
     * std_typanalyze().
 
                arry = construct_array(stats->stavalues[k],
                                       stats->numvalues[k],
-                                      stats->attr->atttypid,
-                                      stats->attrtype->typlen,
-                                      stats->attrtype->typbyval,
-                                      stats->attrtype->typalign);
+                                      stats->statypid[k],
+                                      stats->statyplen[k],
+                                      stats->statypbyval[k],
+                                      stats->statypalign[k]);
                values[i++] = PointerGetDatum(arry);    /* stavaluesN */
            }
            else
            stats->numnumbers[0] = num_mcv;
            stats->stavalues[0] = mcv_values;
            stats->numvalues[0] = num_mcv;
+           /*
+            * Accept the defaults for stats->statypid and others.
+            * They have been set before we were called (see vacuum.h)
+            */
        }
    }
    else if (null_cnt > 0)
            stats->numnumbers[slot_idx] = num_mcv;
            stats->stavalues[slot_idx] = mcv_values;
            stats->numvalues[slot_idx] = num_mcv;
+           /*
+            * Accept the defaults for stats->statypid and others.
+            * They have been set before we were called (see vacuum.h)
+            */
            slot_idx++;
        }
 
            stats->staop[slot_idx] = mystats->ltopr;
            stats->stavalues[slot_idx] = hist_values;
            stats->numvalues[slot_idx] = num_hist;
+           /*
+            * Accept the defaults for stats->statypid and others.
+            * They have been set before we were called (see vacuum.h)
+            */
            slot_idx++;
        }
 
 
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.78 2008/06/19 00:46:06 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.79 2008/07/01 10:33:09 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
    int         numvalues[STATISTIC_NUM_SLOTS];
    Datum      *stavalues[STATISTIC_NUM_SLOTS];
 
+   /*
+    * These fields describe the stavalues[n] element types. They will
+    * be initialized to be the same as the column's that's underlying the
+    * slot, but a custom typanalyze function might want to store an array of
+    * something other than the analyzed column's elements. It should then
+    * overwrite these fields.
+    */
+   Oid         statypid[STATISTIC_NUM_SLOTS];
+   int2        statyplen[STATISTIC_NUM_SLOTS];
+   bool        statypbyval[STATISTIC_NUM_SLOTS];
+   char        statypalign[STATISTIC_NUM_SLOTS];
+
    /*
     * These fields are private to the main ANALYZE code and should not be
     * looked at by type-specific functions.