diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index f917652a08..74b2c4b4e1 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ - + @@ -901,19 +901,6 @@ - - attdistinct - float4 - - - attdistinct, if nonzero, is a user-specified - number-of-distinct-values figure to be used instead of estimating the - number of distinct values during ANALYZE. Nonzero values - have the same meanings as for - pg_statistic.stadistinct - - - attlen int2 @@ -1061,6 +1048,15 @@ + + attoptions + text[] + + + Attribute-level options, as keyword=value strings + + + diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 354fa20edf..7f4cb37e6e 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1,5 +1,5 @@ @@ -39,7 +39,8 @@ ALTER TABLE name ALTER [ COLUMN ] column DROP DEFAULT ALTER [ COLUMN ] column { SET | DROP } NOT NULL ALTER [ COLUMN ] column SET STATISTICS integer - ALTER [ COLUMN ] column SET STATISTICS DISTINCT number + ALTER [ COLUMN ] column SET ( attribute_option = value [, ... ] ) + ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] ) ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } ADD table_constraint DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] @@ -158,14 +159,21 @@ ALTER TABLE name - SET STATISTICS DISTINCT + SET ( attribute_option = value [, ... ] ) + RESET ( attribute_option [, ... ] ) - This form overrides the number-of-distinct-values estimate made by - subsequent - operations. When set to a positive value, 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 n_distinct and + n_distinct_inherited, which override the + number-of-distinct-values estimate made by subsequent + + operations. n_distinct affects the statistics for the table + itself, while n_distinct_inherited affects the statistics + gathered for the table and its inheritance children. When set to a + positive value, 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, 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 diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index cb9f20f3f5..7564ce1448 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -1,5 +1,5 @@ @@ -173,7 +173,7 @@ ANALYZE [ VERBOSE ] [ table [ ( ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT + ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...) (see ). diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 28eacb4e47..65328a9f28 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -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}} }; @@ -1186,6 +1203,37 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate) return DatumGetByteaP(result); } +/* + * 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 */ diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index a39b4922d8..9edecda2d8 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -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), diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 3965896608..14e4b839e4 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -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; diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index 573f4c80a1..008ae46465 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -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. diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 6f0894b214..920e00f101 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -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); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index b84c586a99..ed70f97329 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -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; diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 7d4087c915..f27a6dad2e 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -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); } } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 0c5ccdcb45..e1b4532583 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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) +ATExecSetOptions(Relation rel, const char *colName, Node *options, + bool isReset) { - /* - * 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) -{ - 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; + /* 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); - simple_heap_update(attrelation, &tuple->t_self, 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); - /* keep system catalog indexes current */ - CatalogUpdateIndexes(attrelation, 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); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index af26d80863..c81e8a38ec 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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 ALTER [COLUMN] SET STATISTICS DISTINCT */ - | ALTER opt_column ColId SET STATISTICS DISTINCT NumericOnly + /* ALTER TABLE ALTER [COLUMN] 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 ALTER [COLUMN] 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 ALTER [COLUMN] SET STORAGE */ diff --git a/src/backend/utils/cache/Makefile b/src/backend/utils/cache/Makefile index 1a3d2cc482..617cb677f7 100644 --- a/src/backend/utils/cache/Makefile +++ b/src/backend/utils/cache/Makefile @@ -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 diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 05fc7ad5a4..b0764279e8 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -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; @@ -10797,22 +10797,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) tbinfo->attstattarget[j]); } - /* - * 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]); + } } } diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 62b40dea90..0537c43671 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -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 diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 70b798d2f6..da2011074b 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -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 && diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index f7f5587f7c..2756eabff0 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -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 */ diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index f0de816e59..5381975a51 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -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 @@ -56,13 +56,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 /* ---------------- diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index c752d071d5..1ac74e0ee4 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -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 */