OSDN Git Service

Replace ALTER TABLE ... SET STATISTICS DISTINCT with a more general mechanism.
authorRobert Haas <rhaas@postgresql.org>
Fri, 22 Jan 2010 16:40:19 +0000 (16:40 +0000)
committerRobert Haas <rhaas@postgresql.org>
Fri, 22 Jan 2010 16:40:19 +0000 (16:40 +0000)
Attributes can now have options, just as relations and tablespaces do, and
the reloptions code is used to parse, validate, and store them.  For
simplicity and because these options are not performance critical, we store
them in a separate cache rather than the main relcache.

Thanks to Alex Hunsaker for the review.

19 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/analyze.sgml
src/backend/access/common/reloptions.c
src/backend/access/common/tupdesc.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/genbki.pl
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/analyze.c
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/utils/cache/Makefile
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/psql/tab-complete.c
src/include/access/reloptions.h
src/include/catalog/pg_attribute.h
src/include/nodes/parsenodes.h

index f917652..74b2c4b 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.218 2010/01/17 22:56:21 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.219 2010/01/22 16:40:18 rhaas Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
      </row>
 
      <row>
-      <entry><structfield>attdistinct</structfield></entry>
-      <entry><type>float4</type></entry>
-      <entry></entry>
-      <entry>
-       <structfield>attdistinct</structfield>, if nonzero, is a user-specified
-       number-of-distinct-values figure to be used instead of estimating the
-       number of distinct values during <command>ANALYZE</>.  Nonzero values
-       have the same meanings as for
-       <link linkend="catalog-pg-statistic"><structname>pg_statistic</></link>.<structfield>stadistinct</>
-      </entry>
-     </row>
-
-     <row>
       <entry><structfield>attlen</structfield></entry>
       <entry><type>int2</type></entry>
       <entry></entry>
       </entry>
      </row>
 
+     <row>
+      <entry><structfield>attoptions</structfield></entry>
+      <entry><type>text[]</type></entry>
+      <entry></entry>
+      <entry>
+       Attribute-level options, as <quote>keyword=value</> strings
+      </entry>
+     </row>
+
     </tbody>
    </tgroup>
   </table>
index 354fa20..7f4cb37 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.109 2009/09/18 05:00:41 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.110 2010/01/22 16:40:18 rhaas Exp $
 PostgreSQL documentation
 -->
 
@@ -39,7 +39,8 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> DROP DEFAULT
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
-    ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS DISTINCT <replaceable class="PARAMETER">number</replaceable>
+    ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
+    ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
     ADD <replaceable class="PARAMETER">table_constraint</replaceable>
     DROP CONSTRAINT [ IF EXISTS ]  <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
@@ -158,14 +159,21 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
    </varlistentry>
 
    <varlistentry>
-    <term><literal>SET STATISTICS DISTINCT</literal></term>
+    <term><literal>SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )</term></literal>
+    <term><literal>RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )</literal>
     <listitem>
      <para>
-      This form overrides the number-of-distinct-values estimate made by
-      subsequent <xref linkend="sql-analyze" endterm="sql-analyze-title">
-      operations.  When set to a positive value, <command>ANALYZE</> will
-      assume that the column contains exactly the specified number of distinct
-      nonnull values.  When set to a negative value, which must be greater
+      This form sets or resets attribute-level options.  Currently, the only
+      define attribute-level options are <literal>n_distinct</> and
+      <literal>n_distinct_inherited</>, which override the
+      number-of-distinct-values estimate made by subsequent
+      <xref linkend="sql-analyze" endterm="sql-analyze-title">
+      operations.  <literal>n_distinct</> affects the statistics for the table
+      itself, while <literal>n_distinct_inherited</> affects the statistics
+      gathered for the table and its inheritance children.  When set to a
+      positive value, <command>ANALYZE</> will assume that the column contains
+      exactly the specified number of distinct nonnull values.  When set to a
+      negative value, which must be greater
       than or equal to -1, <command>ANALYZE</> will assume that the number of
       distinct nonnull values in the column is linear in the size of the
       table; the exact count is to be computed by multiplying the estimated
index cb9f20f..7564ce1 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.27 2009/08/04 22:04:37 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.28 2010/01/22 16:40:18 rhaas Exp $
 PostgreSQL documentation
 -->
 
@@ -173,7 +173,7 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
    with the largest possible statistics target.  If this inaccuracy leads to
    bad query plans, a more accurate value can be determined manually and then
    installed with
-   <command>ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT</>
+   <command>ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)</>
    (see <xref linkend="sql-altertable" endterm="sql-altertable-title">).
   </para>
  </refsect1>
index 28eacb4..65328a9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.31 2010/01/05 21:53:58 rhaas Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.32 2010/01/22 16:40:18 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,6 +24,7 @@
 #include "commands/tablespace.h"
 #include "nodes/makefuncs.h"
 #include "utils/array.h"
+#include "utils/attoptcache.h"
 #include "utils/builtins.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
@@ -196,6 +197,22 @@ static relopt_real realRelOpts[] =
                },
                -1, 0.0, DBL_MAX
        },
+       {
+               {
+                       "n_distinct",
+                       "Sets the planner's estimate of the number of distinct values appearing in a column (excluding child relations).",
+                       RELOPT_KIND_ATTRIBUTE
+               },
+               0, -1.0, DBL_MAX
+       },
+       {
+               {
+                       "n_distinct_inherited",
+                       "Sets the planner's estimate of the number of distinct values appearing in a column (including child relations).",
+                       RELOPT_KIND_ATTRIBUTE
+               },
+               0, -1.0, DBL_MAX
+       },
        /* list terminator */
        {{NULL}}
 };
@@ -1187,6 +1204,37 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate)
 }
 
 /*
+ * Option parser for attribute reloptions
+ */
+bytea *
+attribute_reloptions(Datum reloptions, bool validate)
+{
+       relopt_value *options;
+       AttributeOpts  *aopts;
+       int                     numoptions;
+       static const relopt_parse_elt tab[] = {
+               {"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
+               {"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
+       };
+
+       options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
+                                                         &numoptions);
+
+       /* if none set, we're done */
+       if (numoptions == 0)
+               return NULL;
+
+       aopts = allocateReloptStruct(sizeof(AttributeOpts), options, numoptions);
+
+       fillRelOptions((void *) aopts, sizeof(AttributeOpts), options, numoptions,
+                                  validate, tab, lengthof(tab));
+
+       pfree(options);
+
+       return (bytea *) aopts;
+}
+
+/*
  * Option parser for tablespace reloptions
  */
 bytea *
index a39b492..9edecda 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.131 2010/01/02 16:57:33 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.132 2010/01/22 16:40:18 rhaas Exp $
  *
  * NOTES
  *       some of the executor utility code such as "ExecTypeFromTL" should be
@@ -338,8 +338,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
                        return false;
                if (attr1->attstattarget != attr2->attstattarget)
                        return false;
-               if (attr1->attdistinct != attr2->attdistinct)
-                       return false;
                if (attr1->attlen != attr2->attlen)
                        return false;
                if (attr1->attndims != attr2->attndims)
@@ -362,7 +360,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
                        return false;
                if (attr1->attinhcount != attr2->attinhcount)
                        return false;
-               /* attacl is ignored, since it's not even present... */
+               /* attacl and attoptions are not even present... */
        }
 
        if (tupdesc1->constr != NULL)
@@ -467,7 +465,6 @@ TupleDescInitEntry(TupleDesc desc,
                MemSet(NameStr(att->attname), 0, NAMEDATALEN);
 
        att->attstattarget = -1;
-       att->attdistinct = 0;
        att->attcacheoff = -1;
        att->atttypmod = typmod;
 
@@ -479,7 +476,7 @@ TupleDescInitEntry(TupleDesc desc,
        att->attisdropped = false;
        att->attislocal = true;
        att->attinhcount = 0;
-       /* attacl is not set because it's not present in tupledescs */
+       /* attacl and attoptions are not present in tupledescs */
 
        tuple = SearchSysCache(TYPEOID,
                                                   ObjectIdGetDatum(oidtypeid),
index 3965896..14e4b83 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.257 2010/01/20 09:16:23 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.258 2010/01/22 16:40:18 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -737,7 +737,6 @@ DefineAttr(char *name, char *type, int attnum)
        }
 
        attrtypes[attnum]->attstattarget = -1;
-       attrtypes[attnum]->attdistinct = 0;
        attrtypes[attnum]->attcacheoff = -1;
        attrtypes[attnum]->atttypmod = -1;
        attrtypes[attnum]->attislocal = true;
index 573f4c8..008ae46 100644 (file)
@@ -10,7 +10,7 @@
 # Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.6 2010/01/06 22:02:45 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.7 2010/01/22 16:40:18 rhaas Exp $
 #
 #----------------------------------------------------------------------
 
@@ -200,7 +200,8 @@ foreach my $catname ( @{ $catalogs->{names} } )
                 # Store schemapg entries for later.
                 $row = emit_schemapg_row($row, grep { $bki_attr{$_} eq 'bool' } @attnames);
                 push @{ $schemapg_entries{$table_name} },
-                  '{ ' . join(', ', map $row->{$_}, @attnames) . ' }';
+                                       '{ ' . join(', ', grep { defined $_ }
+                                       map $row->{$_}, @attnames) . ' }';
             }
 
             # Generate entries for system attributes.
@@ -351,14 +352,14 @@ sub emit_pgattr_row
 
     # Add in default values for pg_attribute
     my %PGATTR_DEFAULTS = (
-        attdistinct   => '0',
         attcacheoff   => '-1',
         atttypmod     => '-1',
         atthasdef     => 'f',
         attisdropped  => 'f',
         attislocal    => 't',
         attinhcount   => '0',
-        attacl        => '_null_'
+        attacl        => '_null_',
+        attoptions    => '_null_'
     );
     return {%PGATTR_DEFAULTS, %row};
 }
@@ -384,7 +385,11 @@ sub emit_schemapg_row
     $row->{attname}     = q|{"| . $row->{attname}    . q|"}|;
     $row->{attstorage}  = q|'|  . $row->{attstorage} . q|'|;
     $row->{attalign}    = q|'|  . $row->{attalign}   . q|'|;
-    $row->{attacl}      = q|{ 0 }|;
+
+    # We don't emit initializers for the variable length fields at all.
+    # Only the fixed-size portions of the descriptors are ever used.
+    delete $row->{attacl};
+    delete $row->{attoptions};
 
     # Expand booleans from 'f'/'t' to 'false'/'true'.
     # Some values might be other macros (eg FLOAT4PASSBYVAL), don't change.
index 6f0894b..920e00f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.366 2010/01/06 05:18:18 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.367 2010/01/22 16:40:18 rhaas Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -116,40 +116,46 @@ Oid binary_upgrade_next_toast_relfilenode = InvalidOid;
  *             Disadvantage:  special cases will be all over the place.
  */
 
+/*
+ * The initializers below do not include the attoptions or attacl fields,
+ * but that's OK - we're never going to reference anything beyond the
+ * fixed-size portion of the structure anyway.
+ */
+
 static FormData_pg_attribute a1 = {
-       0, {"ctid"}, TIDOID, 0, 0, sizeof(ItemPointerData),
+       0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
        SelfItemPointerAttributeNumber, 0, -1, -1,
-       false, 'p', 's', true, false, false, true, 0, {0}
+       false, 'p', 's', true, false, false, true, 0
 };
 
 static FormData_pg_attribute a2 = {
-       0, {"oid"}, OIDOID, 0, 0, sizeof(Oid),
+       0, {"oid"}, OIDOID, 0, sizeof(Oid),
        ObjectIdAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 static FormData_pg_attribute a3 = {
-       0, {"xmin"}, XIDOID, 0, 0, sizeof(TransactionId),
+       0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
        MinTransactionIdAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 static FormData_pg_attribute a4 = {
-       0, {"cmin"}, CIDOID, 0, 0, sizeof(CommandId),
+       0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
        MinCommandIdAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 static FormData_pg_attribute a5 = {
-       0, {"xmax"}, XIDOID, 0, 0, sizeof(TransactionId),
+       0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
        MaxTransactionIdAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 static FormData_pg_attribute a6 = {
-       0, {"cmax"}, CIDOID, 0, 0, sizeof(CommandId),
+       0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
        MaxCommandIdAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 /*
@@ -159,9 +165,9 @@ static FormData_pg_attribute a6 = {
  * used in SQL.
  */
 static FormData_pg_attribute a7 = {
-       0, {"tableoid"}, OIDOID, 0, 0, sizeof(Oid),
+       0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
        TableOidAttributeNumber, 0, -1, -1,
-       true, 'p', 'i', true, false, false, true, 0, {0}
+       true, 'p', 'i', true, false, false, true, 0
 };
 
 static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
@@ -482,13 +488,12 @@ CheckAttributeType(const char *attname, Oid atttypid)
  *             Construct and insert a new tuple in pg_attribute.
  *
  * Caller has already opened and locked pg_attribute.  new_attribute is the
- * attribute to insert (but we ignore its attacl, if indeed it has one).
+ * attribute to insert (but we ignore attacl and attoptions, which are always
+ * initialized to NULL).
  *
  * indstate is the index state for CatalogIndexInsert. It can be passed as
  * NULL, in which case we'll fetch the necessary info.  (Don't do this when
  * inserting multiple attributes, because it's a tad more expensive.)
- *
- * We always initialize attacl to NULL (i.e., default permissions).
  */
 void
 InsertPgAttributeTuple(Relation pg_attribute_rel,
@@ -507,7 +512,6 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
        values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
        values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
        values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(new_attribute->attstattarget);
-       values[Anum_pg_attribute_attdistinct - 1] = Float4GetDatum(new_attribute->attdistinct);
        values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(new_attribute->attlen);
        values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum);
        values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims);
@@ -522,8 +526,9 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
        values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal);
        values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
 
-       /* start out with empty permissions */
+       /* start out with empty permissions and empty options */
        nulls[Anum_pg_attribute_attacl - 1] = true;
+       nulls[Anum_pg_attribute_attoptions - 1] = true;
 
        tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
 
@@ -578,7 +583,6 @@ AddNewAttributeTuples(Oid new_rel_oid,
                attr->attrelid = new_rel_oid;
                /* Make sure these are OK, too */
                attr->attstattarget = -1;
-               attr->attdistinct = 0;
                attr->attcacheoff = -1;
 
                InsertPgAttributeTuple(rel, attr, indstate);
index b84c586..ed70f97 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.330 2010/01/17 22:56:21 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.331 2010/01/22 16:40:18 rhaas Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -203,7 +203,6 @@ ConstructTupleDescriptor(Relation heapRelation,
                        to->attnum = i + 1;
 
                        to->attstattarget = -1;
-                       to->attdistinct = 0;
                        to->attcacheoff = -1;
                        to->attnotnull = false;
                        to->atthasdef = false;
index 7d4087c..f27a6da 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.147 2010/01/02 16:57:36 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.148 2010/01/22 16:40:18 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,6 +39,7 @@
 #include "storage/proc.h"
 #include "storage/procarray.h"
 #include "utils/acl.h"
+#include "utils/attoptcache.h"
 #include "utils/datum.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
@@ -493,6 +494,8 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
                for (i = 0; i < attr_cnt; i++)
                {
                        VacAttrStats *stats = vacattrstats[i];
+                       AttributeOpts *aopt =
+                               get_attribute_options(onerel->rd_id, stats->attr->attnum);
 
                        stats->rows = rows;
                        stats->tupDesc = onerel->rd_att;
@@ -501,9 +504,17 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
                                                                         numrows,
                                                                         totalrows);
 
-                       /* If attdistinct is set, override with that value */
-                       if (stats->attr->attdistinct != 0)
-                               stats->stadistinct = stats->attr->attdistinct;
+                       /*
+                        * If the appropriate flavor of the n_distinct option is
+                        * specified, override with the corresponding value.
+                        */
+                       if (aopt != NULL)
+                       {
+                               float8  n_distinct =
+                                       inh ? aopt->n_distinct_inherited : aopt->n_distinct;
+                               if (n_distinct != 0.0)
+                                       stats->stadistinct = n_distinct;
+                       }
 
                        MemoryContextResetAndDeleteChildren(col_context);
                }
@@ -751,6 +762,9 @@ compute_index_stats(Relation onerel, double totalrows,
                        for (i = 0; i < attr_cnt; i++)
                        {
                                VacAttrStats *stats = thisdata->vacattrstats[i];
+                               AttributeOpts *aopt =
+                                       get_attribute_options(stats->attr->attrelid,
+                                               stats->attr->attnum);
 
                                stats->exprvals = exprvals + i;
                                stats->exprnulls = exprnulls + i;
@@ -759,9 +773,15 @@ compute_index_stats(Relation onerel, double totalrows,
                                                                                 ind_fetch_func,
                                                                                 numindexrows,
                                                                                 totalindexrows);
-                               /* If attdistinct is set, override with that value */
-                               if (stats->attr->attdistinct != 0)
-                                       stats->stadistinct = stats->attr->attdistinct;
+
+                               /*
+                                * If the n_distinct option is specified, it overrides the
+                                * above computation.  For indices, we always use just
+                                * n_distinct, not n_distinct_inherited.
+                                */
+                               if (aopt != NULL && aopt->n_distinct != 0.0)
+                                       stats->stadistinct = aopt->n_distinct;
+
                                MemoryContextResetAndDeleteChildren(col_context);
                        }
                }
index 0c5ccdc..e1b4532 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.317 2010/01/20 19:43:40 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.318 2010/01/22 16:40:18 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -284,10 +284,8 @@ static void ATPrepSetStatistics(Relation rel, const char *colName,
                                        Node *newValue);
 static void ATExecSetStatistics(Relation rel, const char *colName,
                                        Node *newValue);
-static void ATPrepSetDistinct(Relation rel, const char *colName,
-                                       Node *newValue);
-static void ATExecSetDistinct(Relation rel, const char *colName,
-                                Node *newValue);
+static void ATExecSetOptions(Relation rel, const char *colName,
+                                Node *options, bool isReset);
 static void ATExecSetStorage(Relation rel, const char *colName,
                                 Node *newValue);
 static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
@@ -2425,10 +2423,10 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        ATPrepSetStatistics(rel, cmd->name, cmd->def);
                        pass = AT_PASS_COL_ATTRS;
                        break;
-               case AT_SetDistinct:    /* ALTER COLUMN SET STATISTICS DISTINCT */
-                       ATSimpleRecursion(wqueue, rel, cmd, recurse);
-                       /* Performs own permission checks */
-                       ATPrepSetDistinct(rel, cmd->name, cmd->def);
+               case AT_SetOptions:             /* ALTER COLUMN SET ( options ) */
+               case AT_ResetOptions:   /* ALTER COLUMN RESET ( options ) */
+                       ATSimplePermissionsRelationOrIndex(rel);
+                       /* This command never recurses */
                        pass = AT_PASS_COL_ATTRS;
                        break;
                case AT_SetStorage:             /* ALTER COLUMN SET STORAGE */
@@ -2644,8 +2642,11 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
                case AT_SetStatistics:  /* ALTER COLUMN SET STATISTICS */
                        ATExecSetStatistics(rel, cmd->name, cmd->def);
                        break;
-               case AT_SetDistinct:    /* ALTER COLUMN SET STATISTICS DISTINCT */
-                       ATExecSetDistinct(rel, cmd->name, cmd->def);
+               case AT_SetOptions:             /* ALTER COLUMN SET ( options ) */
+                       ATExecSetOptions(rel, cmd->name, cmd->def, false);
+                       break;
+               case AT_ResetOptions:   /* ALTER COLUMN RESET ( options ) */
+                       ATExecSetOptions(rel, cmd->name, cmd->def, true);
                        break;
                case AT_SetStorage:             /* ALTER COLUMN SET STORAGE */
                        ATExecSetStorage(rel, cmd->name, cmd->def);
@@ -3682,7 +3683,6 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
        namestrcpy(&(attribute.attname), colDef->colname);
        attribute.atttypid = typeOid;
        attribute.attstattarget = (newattnum > 0) ? -1 : 0;
-       attribute.attdistinct = 0;
        attribute.attlen = tform->typlen;
        attribute.attcacheoff = -1;
        attribute.atttypmod = typmod;
@@ -4151,68 +4151,24 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue)
        heap_close(attrelation, RowExclusiveLock);
 }
 
-/*
- * ALTER TABLE ALTER COLUMN SET STATISTICS DISTINCT
- */
-static void
-ATPrepSetDistinct(Relation rel, const char *colName, Node *newValue)
-{
-       /*
-        * We do our own permission checking because (a) we want to allow SET
-        * DISTINCT on indexes (for expressional index columns), and (b) we want
-        * to allow SET DISTINCT on system catalogs without requiring
-        * allowSystemTableMods to be turned on.
-        */
-       if (rel->rd_rel->relkind != RELKIND_RELATION &&
-               rel->rd_rel->relkind != RELKIND_INDEX)
-               ereport(ERROR,
-                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                                errmsg("\"%s\" is not a table or index",
-                                               RelationGetRelationName(rel))));
-
-       /* Permissions checks */
-       if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
-               aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
-                                          RelationGetRelationName(rel));
-}
-
 static void
-ATExecSetDistinct(Relation rel, const char *colName, Node *newValue)
+ATExecSetOptions(Relation rel, const char *colName, Node *options,
+                                bool isReset)
 {
-       float4          newdistinct;
        Relation        attrelation;
-       HeapTuple       tuple;
+       HeapTuple       tuple,
+                               newtuple;
        Form_pg_attribute attrtuple;
-
-       switch (nodeTag(newValue))
-       {
-               case T_Integer:
-                       newdistinct = intVal(newValue);
-                       break;
-               case T_Float:
-                       newdistinct = floatVal(newValue);
-                       break;
-               default:
-                       elog(ERROR, "unrecognized node type: %d",
-                                (int) nodeTag(newValue));
-                       newdistinct = 0;        /* keep compiler quiet */
-                       break;
-       }
-
-       /*
-        * Limit ndistinct to sane values
-        */
-       if (newdistinct < -1.0)
-       {
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg("number of distinct values %g is too low",
-                                               newdistinct)));
-       }
+       Datum           datum,
+                               newOptions;
+       bool            isnull;
+       Datum           repl_val[Natts_pg_attribute];
+       bool            repl_null[Natts_pg_attribute];
+       bool            repl_repl[Natts_pg_attribute];
 
        attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
 
-       tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
+       tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
 
        if (!HeapTupleIsValid(tuple))
                ereport(ERROR,
@@ -4227,14 +4183,32 @@ ATExecSetDistinct(Relation rel, const char *colName, Node *newValue)
                                 errmsg("cannot alter system column \"%s\"",
                                                colName)));
 
-       attrtuple->attdistinct = newdistinct;
-
-       simple_heap_update(attrelation, &tuple->t_self, tuple);
+       /* Generate new proposed attoptions (text array) */
+       Assert(IsA(options, List));
+       datum = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions,
+               &isnull);
+       newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
+                                                                        (List *) options, NULL, NULL, false,
+                                                                        isReset);
+       /* Validate new options */
+       (void) attribute_reloptions(newOptions, true);
 
-       /* keep system catalog indexes current */
-       CatalogUpdateIndexes(attrelation, tuple);
+       /* Build new tuple. */
+       memset(repl_null, false, sizeof(repl_null));
+       memset(repl_repl, false, sizeof(repl_repl));
+       if (newOptions != (Datum) 0)
+               repl_val[Anum_pg_attribute_attoptions - 1] = newOptions;
+       else
+               repl_null[Anum_pg_attribute_attoptions - 1] = true;
+       repl_repl[Anum_pg_attribute_attoptions - 1] = true;
+       newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation),
+                                                                repl_val, repl_null, repl_repl);
+       ReleaseSysCache(tuple);
 
-       heap_freetuple(tuple);
+       /* Update system catalog. */
+       simple_heap_update(attrelation, &newtuple->t_self, newtuple);
+       CatalogUpdateIndexes(attrelation, newtuple);
+       heap_freetuple(newtuple);
 
        heap_close(attrelation, RowExclusiveLock);
 }
index af26d80..c81e8a3 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.703 2010/01/06 05:31:13 itagaki Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.704 2010/01/22 16:40:18 rhaas Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -1645,13 +1645,22 @@ alter_table_cmd:
                                        n->def = (Node *) makeInteger($6);
                                        $$ = (Node *)n;
                                }
-                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS DISTINCT <NumericOnly> */
-                       | ALTER opt_column ColId SET STATISTICS DISTINCT NumericOnly
+                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
+                       | ALTER opt_column ColId SET reloptions
                                {
                                        AlterTableCmd *n = makeNode(AlterTableCmd);
-                                       n->subtype = AT_SetDistinct;
+                                       n->subtype = AT_SetOptions;
                                        n->name = $3;
-                                       n->def = (Node *) $7;
+                                       n->def = (Node *) $5;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
+                       | ALTER opt_column ColId RESET reloptions
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_ResetOptions;
+                                       n->name = $3;
+                                       n->def = (Node *) $5;
                                        $$ = (Node *)n;
                                }
                        /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
index 1a3d2cc..617cb67 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for utils/cache
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.24 2010/01/05 21:53:59 rhaas Exp $
+#    $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.25 2010/01/22 16:40:19 rhaas Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ subdir = src/backend/utils/cache
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = catcache.o inval.o plancache.o relcache.o \
+OBJS = attoptcache.o catcache.o inval.o plancache.o relcache.o \
        spccache.o syscache.o lsyscache.o typcache.o ts_cache.o
 
 include $(top_srcdir)/src/backend/common.mk
index 05fc7ad..b076427 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.567 2010/01/17 22:56:22 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.568 2010/01/22 16:40:19 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -5056,7 +5056,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        int                     i_atttypname;
        int                     i_atttypmod;
        int                     i_attstattarget;
-       int                     i_attdistinct;
        int                     i_attstorage;
        int                     i_typstorage;
        int                     i_attnotnull;
@@ -5065,6 +5064,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        int                     i_attlen;
        int                     i_attalign;
        int                     i_attislocal;
+       int                     i_attoptions;
        PGresult   *res;
        int                     ntups;
        bool            hasdefaults;
@@ -5104,13 +5104,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
                if (g_fout->remoteVersion >= 80500)
                {
-                       /* attdistinct is new in 8.5 */
+                       /* attoptions is new in 8.5 */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
-                                                         "a.attstattarget, a.attdistinct, "
-                                                         "a.attstorage, t.typstorage, "
+                                                         "a.attstattarget, a.attstorage, t.typstorage, "
                                                          "a.attnotnull, a.atthasdef, a.attisdropped, "
                                                          "a.attlen, a.attalign, a.attislocal, "
-                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname "
+                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
+                                                       "array_to_string(attoptions, ', ') AS attoptions "
                         "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
                                                          "ON a.atttypid = t.oid "
                                                          "WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5122,11 +5122,11 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                {
                        /* need left join here to not fail on dropped columns ... */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
-                                                         "a.attstattarget, 0 AS attdistinct, "
-                                                         "a.attstorage, t.typstorage, "
+                                                         "a.attstattarget, a.attstorage, t.typstorage, "
                                                          "a.attnotnull, a.atthasdef, a.attisdropped, "
                                                          "a.attlen, a.attalign, a.attislocal, "
-                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname "
+                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
+                                                         "'' AS attoptions "
                         "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
                                                          "ON a.atttypid = t.oid "
                                                          "WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5142,12 +5142,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                         * explicitly set or was just a default.
                         */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
-                                                         "-1 AS attstattarget, 0 AS attdistinct, "
-                                                         "a.attstorage, "
+                                                         "-1 AS attstattarget, a.attstorage, "
                                                          "t.typstorage, a.attnotnull, a.atthasdef, "
                                                          "false AS attisdropped, a.attlen, "
                                                          "a.attalign, false AS attislocal, "
-                                                         "format_type(t.oid,a.atttypmod) AS atttypname "
+                                                         "format_type(t.oid,a.atttypmod) AS atttypname, "
+                                                         "'' AS attoptions "
                                                          "FROM pg_attribute a LEFT JOIN pg_type t "
                                                          "ON a.atttypid = t.oid "
                                                          "WHERE a.attrelid = '%u'::oid "
@@ -5159,12 +5159,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                {
                        /* format_type not available before 7.1 */
                        appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, "
-                                                         "-1 AS attstattarget, 0 AS attdistinct, "
+                                                         "-1 AS attstattarget, "
                                                          "attstorage, attstorage AS typstorage, "
                                                          "attnotnull, atthasdef, false AS attisdropped, "
                                                          "attlen, attalign, "
                                                          "false AS attislocal, "
-                                                         "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname "
+                                                         "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname, "
+                                                         "'' AS attoptions "
                                                          "FROM pg_attribute a "
                                                          "WHERE attrelid = '%u'::oid "
                                                          "AND attnum > 0::int2 "
@@ -5182,7 +5183,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                i_atttypname = PQfnumber(res, "atttypname");
                i_atttypmod = PQfnumber(res, "atttypmod");
                i_attstattarget = PQfnumber(res, "attstattarget");
-               i_attdistinct = PQfnumber(res, "attdistinct");
                i_attstorage = PQfnumber(res, "attstorage");
                i_typstorage = PQfnumber(res, "typstorage");
                i_attnotnull = PQfnumber(res, "attnotnull");
@@ -5191,13 +5191,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                i_attlen = PQfnumber(res, "attlen");
                i_attalign = PQfnumber(res, "attalign");
                i_attislocal = PQfnumber(res, "attislocal");
+               i_attoptions = PQfnumber(res, "attoptions");
 
                tbinfo->numatts = ntups;
                tbinfo->attnames = (char **) malloc(ntups * sizeof(char *));
                tbinfo->atttypnames = (char **) malloc(ntups * sizeof(char *));
                tbinfo->atttypmod = (int *) malloc(ntups * sizeof(int));
                tbinfo->attstattarget = (int *) malloc(ntups * sizeof(int));
-               tbinfo->attdistinct = (float4 *) malloc(ntups * sizeof(float4));
                tbinfo->attstorage = (char *) malloc(ntups * sizeof(char));
                tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
                tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
@@ -5206,6 +5206,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
+               tbinfo->attoptions = (char **) malloc(ntups * sizeof(char *));
                tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->inhAttrDef = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->inhNotNull = (bool *) malloc(ntups * sizeof(bool));
@@ -5223,8 +5224,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        tbinfo->atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname));
                        tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
                        tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget));
-                       tbinfo->attdistinct[j] = strtod(PQgetvalue(res, j, i_attdistinct),
-                                                                                       (char **) NULL);
                        tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
                        tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
                        tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
@@ -5232,6 +5231,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        tbinfo->attalign[j] = *(PQgetvalue(res, j, i_attalign));
                        tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
                        tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
+                       tbinfo->attoptions[j] = strdup(PQgetvalue(res, j, i_attoptions));
                        tbinfo->attrdefs[j] = NULL; /* fix below */
                        if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
                                hasdefaults = true;
@@ -10798,22 +10798,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        }
 
                        /*
-                        * Dump per-column ndistinct information. We only issue an ALTER
-                        * TABLE statement if the attdistinct entry for this column is
-                        * non-zero (i.e. it's not the default value)
-                        */
-                       if (tbinfo->attdistinct[j] != 0 &&
-                               !tbinfo->attisdropped[j])
-                       {
-                               appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                 fmtId(tbinfo->dobj.name));
-                               appendPQExpBuffer(q, "ALTER COLUMN %s ",
-                                                                 fmtId(tbinfo->attnames[j]));
-                               appendPQExpBuffer(q, "SET STATISTICS DISTINCT %g;\n",
-                                                                 tbinfo->attdistinct[j]);
-                       }
-
-                       /*
                         * Dump per-column storage information.  The statement is only
                         * dumped if the storage has been changed from the type's default.
                         */
@@ -10850,6 +10834,19 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                          storage);
                                }
                        }
+
+                       /*
+                        * Dump per-column attributes.
+                        */
+                       if (tbinfo->attoptions[j] && tbinfo->attoptions[j][0] != '\0')
+                       {
+                               appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+                                                                 fmtId(tbinfo->dobj.name));
+                               appendPQExpBuffer(q, "ALTER COLUMN %s ",
+                                                                 fmtId(tbinfo->attnames[j]));
+                               appendPQExpBuffer(q, "SET (%s);\n",
+                                                                 tbinfo->attoptions[j]);
+                       }
                }
        }
 
index 62b40de..0537c43 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.160 2010/01/02 16:57:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.161 2010/01/22 16:40:19 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -244,13 +244,13 @@ typedef struct _tableInfo
        char      **atttypnames;        /* attribute type names */
        int                *atttypmod;          /* type-specific type modifiers */
        int                *attstattarget;      /* attribute statistics targets */
-       float4     *attdistinct;        /* override ndistinct calculation */
        char       *attstorage;         /* attribute storage scheme */
        char       *typstorage;         /* type storage scheme */
        bool       *attisdropped;       /* true if attr is dropped; don't dump it */
        int                *attlen;                     /* attribute length, used by binary_upgrade */
        char       *attalign;           /* attribute align, used by binary_upgrade */
        bool       *attislocal;         /* true if attr has local definition */
+       char      **attoptions;         /* per-attribute options */
 
        /*
         * Note: we need to store per-attribute notnull, default, and constraint
index 70b798d..da20110 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2010, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.190 2010/01/02 21:28:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.191 2010/01/22 16:40:19 rhaas Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -992,17 +992,6 @@ psql_completion(char *text, int start, int end)
 
                COMPLETE_WITH_LIST(list_COLUMNSET);
        }
-       else if (((pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
-                          pg_strcasecmp(prev4_wd, "COLUMN") == 0) ||
-                         pg_strcasecmp(prev4_wd, "ALTER") == 0) &&
-                        pg_strcasecmp(prev2_wd, "SET") == 0 &&
-                        pg_strcasecmp(prev_wd, "STATISTICS") == 0)
-       {
-               static const char *const list_COLUMNSETSTATS[] =
-               {"DISTINCT", NULL};
-
-               COMPLETE_WITH_LIST(list_COLUMNSETSTATS);
-       }
        else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
                           pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
                          (pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
index f7f5587..2756eab 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.18 2010/01/05 21:53:59 rhaas Exp $
+ * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.19 2010/01/22 16:40:19 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,7 +40,8 @@ typedef enum relopt_kind
        RELOPT_KIND_HASH = (1 << 3),
        RELOPT_KIND_GIN = (1 << 4),
        RELOPT_KIND_GIST = (1 << 5),
-       RELOPT_KIND_TABLESPACE = (1 << 6),
+       RELOPT_KIND_ATTRIBUTE = (1 << 6),
+       RELOPT_KIND_TABLESPACE = (1 << 7),
        /* if you add a new kind, make sure you update "last_default" too */
        RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_TABLESPACE,
        /* some compilers treat enums as signed ints, so we can't use 1 << 31 */
@@ -266,6 +267,7 @@ extern bytea *default_reloptions(Datum reloptions, bool validate,
 extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
 extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions,
                                 bool validate);
+extern bytea *attribute_reloptions(Datum reloptions, bool validate);
 extern bytea *tablespace_reloptions(Datum reloptions, bool validate);
 
 #endif   /* RELOPTIONS_H */
index f0de816..5381975 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.157 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.158 2010/01/22 16:40:19 rhaas Exp $
  *
  * NOTES
  *       the genbki.pl script reads this file and generates .bki
@@ -57,13 +57,6 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK
        int4            attstattarget;
 
        /*
-        * attdistinct, if nonzero, is a user-specified ndistinct value to be used
-        * instead of estimating the number of distinct values during ANALYZE.
-        * Nonzero values have the same meanings as for pg_statistic.stadistinct.
-        */
-       float4          attdistinct;
-
-       /*
         * attlen is a copy of the typlen field from pg_type for this attribute.
         * See atttypid comments above.
         */
@@ -157,6 +150,9 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK
 
        /* Column-level access permissions */
        aclitem         attacl[1];
+
+       /* Column-level options */
+       text            attoptions[1];
 } FormData_pg_attribute;
 
 /*
@@ -185,21 +181,21 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 #define Anum_pg_attribute_attname              2
 #define Anum_pg_attribute_atttypid             3
 #define Anum_pg_attribute_attstattarget 4
-#define Anum_pg_attribute_attdistinct  5
-#define Anum_pg_attribute_attlen               6
-#define Anum_pg_attribute_attnum               7
-#define Anum_pg_attribute_attndims             8
-#define Anum_pg_attribute_attcacheoff  9
-#define Anum_pg_attribute_atttypmod            10
-#define Anum_pg_attribute_attbyval             11
-#define Anum_pg_attribute_attstorage   12
-#define Anum_pg_attribute_attalign             13
-#define Anum_pg_attribute_attnotnull   14
-#define Anum_pg_attribute_atthasdef            15
-#define Anum_pg_attribute_attisdropped 16
-#define Anum_pg_attribute_attislocal   17
-#define Anum_pg_attribute_attinhcount  18
-#define Anum_pg_attribute_attacl               19
+#define Anum_pg_attribute_attlen               5
+#define Anum_pg_attribute_attnum               6
+#define Anum_pg_attribute_attndims             7
+#define Anum_pg_attribute_attcacheoff  8
+#define Anum_pg_attribute_atttypmod            9
+#define Anum_pg_attribute_attbyval             10
+#define Anum_pg_attribute_attstorage   11
+#define Anum_pg_attribute_attalign             12
+#define Anum_pg_attribute_attnotnull   13
+#define Anum_pg_attribute_atthasdef            14
+#define Anum_pg_attribute_attisdropped 15
+#define Anum_pg_attribute_attislocal   16
+#define Anum_pg_attribute_attinhcount  17
+#define Anum_pg_attribute_attacl               18
+#define Anum_pg_attribute_attoptions   19
 
 
 /* ----------------
index c752d07..1ac74e0 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.425 2010/01/17 22:56:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.426 2010/01/22 16:40:19 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1101,7 +1101,8 @@ typedef enum AlterTableType
        AT_DropNotNull,                         /* alter column drop not null */
        AT_SetNotNull,                          /* alter column set not null */
        AT_SetStatistics,                       /* alter column set statistics */
-       AT_SetDistinct,                         /* alter column set statistics distinct */
+       AT_SetOptions,                          /* alter column set ( options ) */
+       AT_ResetOptions,                        /* alter column reset ( options ) */
        AT_SetStorage,                          /* alter column set storage */
        AT_DropColumn,                          /* drop column */
        AT_DropColumnRecurse,           /* internal to commands/tablecmds.c */