diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/access/common/reloptions.c | 50 | ||||
| -rw-r--r-- | src/backend/access/common/tupdesc.c | 9 | ||||
| -rw-r--r-- | src/backend/bootstrap/bootstrap.c | 3 | ||||
| -rw-r--r-- | src/backend/catalog/genbki.pl | 15 | ||||
| -rw-r--r-- | src/backend/catalog/heap.c | 46 | ||||
| -rw-r--r-- | src/backend/catalog/index.c | 3 | ||||
| -rw-r--r-- | src/backend/commands/analyze.c | 34 | ||||
| -rw-r--r-- | src/backend/commands/tablecmds.c | 120 | ||||
| -rw-r--r-- | src/backend/parser/gram.y | 19 | ||||
| -rw-r--r-- | src/backend/utils/cache/Makefile | 4 |
10 files changed, 179 insertions, 124 deletions
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}} }; @@ -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 * 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) -{ - /* - * 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); } 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 <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> */ 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 |
