Commit 90725929 authored by Tom Lane's avatar Tom Lane

Add ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT

Robert Haas
parent 527f0ae3
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.203 2009/07/29 20:56:17 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.204 2009/08/02 22:14:51 tgl Exp $ -->
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
...@@ -886,6 +886,19 @@ ...@@ -886,6 +886,19 @@
</entry> </entry>
</row> </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> <row>
<entry><structfield>attlen</structfield></entry> <entry><structfield>attlen</structfield></entry>
<entry><type>int2</type></entry> <entry><type>int2</type></entry>
...@@ -4303,9 +4316,10 @@ ...@@ -4303,9 +4316,10 @@
<entry></entry> <entry></entry>
<entry>The number of distinct nonnull data values in the column. <entry>The number of distinct nonnull data values in the column.
A value greater than zero is the actual number of distinct values. A value greater than zero is the actual number of distinct values.
A value less than zero is the negative of a fraction of the number A value less than zero is the negative of a multiplier for the number
of rows in the table (for example, a column in which values appear about of rows in the table; for example, a column in which values appear about
twice on the average could be represented by <structfield>stadistinct</> = -0.5). twice on the average could be represented by
<structfield>stadistinct</> = -0.5.
A zero value means the number of distinct values is unknown A zero value means the number of distinct values is unknown
</entry> </entry>
</row> </row>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.107 2009/07/20 02:42:27 adunstan Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.108 2009/08/02 22:14:51 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -39,6 +39,7 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -39,6 +39,7 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> DROP DEFAULT 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 | 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 <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 STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD <replaceable class="PARAMETER">table_constraint</replaceable> ADD <replaceable class="PARAMETER">table_constraint</replaceable>
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ] DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
...@@ -90,8 +91,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -90,8 +91,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
dropped as well. You will need to say <literal>CASCADE</> if dropped as well. You will need to say <literal>CASCADE</> if
anything outside the table depends on the column, for example, anything outside the table depends on the column, for example,
foreign key references or views. foreign key references or views.
If <literal>IF EXISTS</literal> is specified and the column If <literal>IF EXISTS</literal> is specified and the column
does not exist, no error is thrown. In this case a notice does not exist, no error is thrown. In this case a notice
is issued instead. is issued instead.
</para> </para>
</listitem> </listitem>
...@@ -156,6 +157,31 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -156,6 +157,31 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>SET STATISTICS DISTINCT</literal></term>
<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
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
table size by the absolute value of the given number. For example,
a value of -1 implies that all values in the column are distinct, while
a value of -0.5 implies that each value appears twice on the average.
This can be useful when the size of the table changes over time, since
the multiplication by the number of rows in the table is not performed
until query planning time. Specify a value of 0 to revert to estimating
the number of distinct values normally. For more information on the use
of statistics by the <productname>PostgreSQL</productname> query
planner, refer to <xref linkend="planner-stats">.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<indexterm> <indexterm>
<primary>TOAST</primary> <primary>TOAST</primary>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.25 2008/12/13 19:13:44 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.26 2009/08/02 22:14:51 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -165,6 +165,17 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re ...@@ -165,6 +165,17 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
the target causes a proportional increase in the time and space needed the target causes a proportional increase in the time and space needed
to do <command>ANALYZE</command>. to do <command>ANALYZE</command>.
</para> </para>
<para>
One of the values estimated by <command>ANALYZE</command> is the number of
distinct values that appear in each column. Because only a subset of the
rows are examined, this estimate can sometimes be quite inaccurate, even
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</>
(see <xref linkend="sql-altertable" endterm="sql-altertable-title">).
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.127 2009/07/16 06:33:42 petere Exp $ * $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.128 2009/08/02 22:14:51 tgl Exp $
* *
* NOTES * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
...@@ -338,6 +338,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) ...@@ -338,6 +338,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false; return false;
if (attr1->attstattarget != attr2->attstattarget) if (attr1->attstattarget != attr2->attstattarget)
return false; return false;
if (attr1->attdistinct != attr2->attdistinct)
return false;
if (attr1->attlen != attr2->attlen) if (attr1->attlen != attr2->attlen)
return false; return false;
if (attr1->attndims != attr2->attndims) if (attr1->attndims != attr2->attndims)
...@@ -465,6 +467,7 @@ TupleDescInitEntry(TupleDesc desc, ...@@ -465,6 +467,7 @@ TupleDescInitEntry(TupleDesc desc,
MemSet(NameStr(att->attname), 0, NAMEDATALEN); MemSet(NameStr(att->attname), 0, NAMEDATALEN);
att->attstattarget = -1; att->attstattarget = -1;
att->attdistinct = 0;
att->attcacheoff = -1; att->attcacheoff = -1;
att->atttypmod = typmod; att->atttypmod = typmod;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.251 2009/07/31 20:26:22 tgl Exp $ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.252 2009/08/02 22:14:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -757,6 +757,7 @@ DefineAttr(char *name, char *type, int attnum) ...@@ -757,6 +757,7 @@ DefineAttr(char *name, char *type, int attnum)
} }
attrtypes[attnum]->attstattarget = -1; attrtypes[attnum]->attstattarget = -1;
attrtypes[attnum]->attdistinct = 0;
attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->atttypmod = -1;
attrtypes[attnum]->attislocal = true; attrtypes[attnum]->attislocal = true;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.356 2009/07/30 02:45:36 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.357 2009/08/02 22:14:52 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -111,37 +111,37 @@ static List *insert_ordered_unique_oid(List *list, Oid datum); ...@@ -111,37 +111,37 @@ static List *insert_ordered_unique_oid(List *list, Oid datum);
*/ */
static FormData_pg_attribute a1 = { static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData), 0, {"ctid"}, TIDOID, 0, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1, SelfItemPointerAttributeNumber, 0, -1, -1,
false, 'p', 's', true, false, false, true, 0, {0} false, 'p', 's', true, false, false, true, 0, {0}
}; };
static FormData_pg_attribute a2 = { static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid), 0, {"oid"}, OIDOID, 0, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1, ObjectIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
static FormData_pg_attribute a3 = { static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId), 0, {"xmin"}, XIDOID, 0, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1, MinTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
static FormData_pg_attribute a4 = { static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId), 0, {"cmin"}, CIDOID, 0, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1, MinCommandIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
static FormData_pg_attribute a5 = { static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId), 0, {"xmax"}, XIDOID, 0, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1, MaxTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
static FormData_pg_attribute a6 = { static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId), 0, {"cmax"}, CIDOID, 0, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1, MaxCommandIdAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
...@@ -153,7 +153,7 @@ static FormData_pg_attribute a6 = { ...@@ -153,7 +153,7 @@ static FormData_pg_attribute a6 = {
* used in SQL. * used in SQL.
*/ */
static FormData_pg_attribute a7 = { static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid), 0, {"tableoid"}, OIDOID, 0, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1, TableOidAttributeNumber, 0, -1, -1,
true, 'p', 'i', true, false, false, true, 0, {0} true, 'p', 'i', true, false, false, true, 0, {0}
}; };
...@@ -501,6 +501,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel, ...@@ -501,6 +501,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname); values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid); values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(new_attribute->attstattarget); 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_attlen - 1] = Int16GetDatum(new_attribute->attlen);
values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum); values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum);
values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims); values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims);
...@@ -571,6 +572,7 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -571,6 +572,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
attr->attrelid = new_rel_oid; attr->attrelid = new_rel_oid;
/* Make sure these are OK, too */ /* Make sure these are OK, too */
attr->attstattarget = -1; attr->attstattarget = -1;
attr->attdistinct = 0;
attr->attcacheoff = -1; attr->attcacheoff = -1;
InsertPgAttributeTuple(rel, attr, indstate); InsertPgAttributeTuple(rel, attr, indstate);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.320 2009/07/29 20:56:18 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.321 2009/08/02 22:14:52 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -192,6 +192,7 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -192,6 +192,7 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attnum = i + 1; to->attnum = i + 1;
to->attstattarget = -1; to->attstattarget = -1;
to->attdistinct = 0;
to->attcacheoff = -1; to->attcacheoff = -1;
to->attnotnull = false; to->attnotnull = false;
to->atthasdef = false; to->atthasdef = false;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.139 2009/06/11 14:48:55 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.140 2009/08/02 22:14:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -425,6 +425,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, ...@@ -425,6 +425,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
std_fetch_func, std_fetch_func,
numrows, numrows,
totalrows); totalrows);
/* If attdistinct is set, override with that value */
if (stats->attr->attdistinct != 0)
stats->stadistinct = stats->attr->attdistinct;
MemoryContextResetAndDeleteChildren(col_context); MemoryContextResetAndDeleteChildren(col_context);
} }
...@@ -679,6 +684,9 @@ compute_index_stats(Relation onerel, double totalrows, ...@@ -679,6 +684,9 @@ compute_index_stats(Relation onerel, double totalrows,
ind_fetch_func, ind_fetch_func,
numindexrows, numindexrows,
totalindexrows); totalindexrows);
/* If attdistinct is set, override with that value */
if (stats->attr->attdistinct != 0)
stats->stadistinct = stats->attr->attdistinct;
MemoryContextResetAndDeleteChildren(col_context); MemoryContextResetAndDeleteChildren(col_context);
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.294 2009/07/30 02:45:36 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.295 2009/08/02 22:14:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -280,9 +280,13 @@ static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, ...@@ -280,9 +280,13 @@ static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
static void ATExecColumnDefault(Relation rel, const char *colName, static void ATExecColumnDefault(Relation rel, const char *colName,
Node *newDefault); Node *newDefault);
static void ATPrepSetStatistics(Relation rel, const char *colName, static void ATPrepSetStatistics(Relation rel, const char *colName,
Node *flagValue); Node *newValue);
static void ATExecSetStatistics(Relation rel, const char *colName, static void ATExecSetStatistics(Relation rel, const char *colName,
Node *newValue); Node *newValue);
static void ATPrepSetDistinct(Relation rel, const char *colName,
Node *newValue);
static void ATExecSetDistinct(Relation rel, const char *colName,
Node *newValue);
static void ATExecSetStorage(Relation rel, const char *colName, static void ATExecSetStorage(Relation rel, const char *colName,
Node *newValue); Node *newValue);
static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName, static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
...@@ -2399,13 +2403,19 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, ...@@ -2399,13 +2403,19 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
/* No command-specific prep needed */ /* No command-specific prep needed */
pass = AT_PASS_ADD_CONSTR; pass = AT_PASS_ADD_CONSTR;
break; break;
case AT_SetStatistics: /* ALTER COLUMN STATISTICS */ case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
ATSimpleRecursion(wqueue, rel, cmd, recurse); ATSimpleRecursion(wqueue, rel, cmd, recurse);
/* Performs own permission checks */ /* Performs own permission checks */
ATPrepSetStatistics(rel, cmd->name, cmd->def); ATPrepSetStatistics(rel, cmd->name, cmd->def);
pass = AT_PASS_COL_ATTRS; pass = AT_PASS_COL_ATTRS;
break; break;
case AT_SetStorage: /* ALTER COLUMN STORAGE */ case AT_SetDistinct: /* ALTER COLUMN SET STATISTICS DISTINCT */
ATSimpleRecursion(wqueue, rel, cmd, recurse);
/* Performs own permission checks */
ATPrepSetDistinct(rel, cmd->name, cmd->def);
pass = AT_PASS_COL_ATTRS;
break;
case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
ATSimplePermissions(rel, false); ATSimplePermissions(rel, false);
ATSimpleRecursion(wqueue, rel, cmd, recurse); ATSimpleRecursion(wqueue, rel, cmd, recurse);
/* No command-specific prep needed */ /* No command-specific prep needed */
...@@ -2616,10 +2626,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, ...@@ -2616,10 +2626,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
ATExecSetNotNull(tab, rel, cmd->name); ATExecSetNotNull(tab, rel, cmd->name);
break; break;
case AT_SetStatistics: /* ALTER COLUMN STATISTICS */ case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
ATExecSetStatistics(rel, cmd->name, cmd->def); ATExecSetStatistics(rel, cmd->name, cmd->def);
break; break;
case AT_SetStorage: /* ALTER COLUMN STORAGE */ case AT_SetDistinct: /* ALTER COLUMN SET STATISTICS DISTINCT */
ATExecSetDistinct(rel, cmd->name, cmd->def);
break;
case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
ATExecSetStorage(rel, cmd->name, cmd->def); ATExecSetStorage(rel, cmd->name, cmd->def);
break; break;
case AT_DropColumn: /* DROP COLUMN */ case AT_DropColumn: /* DROP COLUMN */
...@@ -3620,6 +3633,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, ...@@ -3620,6 +3633,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
namestrcpy(&(attribute.attname), colDef->colname); namestrcpy(&(attribute.attname), colDef->colname);
attribute.atttypid = typeOid; attribute.atttypid = typeOid;
attribute.attstattarget = (newattnum > 0) ? -1 : 0; attribute.attstattarget = (newattnum > 0) ? -1 : 0;
attribute.attdistinct = 0;
attribute.attlen = tform->typlen; attribute.attlen = tform->typlen;
attribute.attcacheoff = -1; attribute.attcacheoff = -1;
attribute.atttypmod = typmod; attribute.atttypmod = typmod;
...@@ -4007,7 +4021,7 @@ ATExecColumnDefault(Relation rel, const char *colName, ...@@ -4007,7 +4021,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
* ALTER TABLE ALTER COLUMN SET STATISTICS * ALTER TABLE ALTER COLUMN SET STATISTICS
*/ */
static void static void
ATPrepSetStatistics(Relation rel, const char *colName, Node *flagValue) ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue)
{ {
/* /*
* We do our own permission checking because (a) we want to allow SET * We do our own permission checking because (a) we want to allow SET
...@@ -4087,6 +4101,94 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue) ...@@ -4087,6 +4101,94 @@ ATExecSetStatistics(Relation rel, const char *colName, Node *newValue)
heap_close(attrelation, RowExclusiveLock); 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)
{
float4 newdistinct;
Relation attrelation;
HeapTuple tuple;
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)));
}
attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
colName, RelationGetRelationName(rel))));
attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
if (attrtuple->attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot alter system column \"%s\"",
colName)));
attrtuple->attdistinct = newdistinct;
simple_heap_update(attrelation, &tuple->t_self, tuple);
/* keep system catalog indexes current */
CatalogUpdateIndexes(attrelation, tuple);
heap_freetuple(tuple);
heap_close(attrelation, RowExclusiveLock);
}
/* /*
* ALTER TABLE ALTER COLUMN SET STORAGE * ALTER TABLE ALTER COLUMN SET STORAGE
*/ */
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.675 2009/07/30 02:45:37 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.676 2009/08/02 22:14:52 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -1605,6 +1605,15 @@ alter_table_cmd: ...@@ -1605,6 +1605,15 @@ alter_table_cmd:
n->def = (Node *) makeInteger($6); n->def = (Node *) makeInteger($6);
$$ = (Node *)n; $$ = (Node *)n;
} }
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS DISTINCT <NumericOnly> */
| ALTER opt_column ColId SET STATISTICS DISTINCT NumericOnly
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_SetDistinct;
n->name = $3;
n->def = (Node *) $7;
$$ = (Node *)n;
}
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */ /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
| ALTER opt_column ColId SET STORAGE ColId | ALTER opt_column ColId SET STORAGE ColId
{ {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.543 2009/07/29 20:56:19 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.544 2009/08/02 22:14:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -4707,6 +4707,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4707,6 +4707,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
int i_atttypname; int i_atttypname;
int i_atttypmod; int i_atttypmod;
int i_attstattarget; int i_attstattarget;
int i_attdistinct;
int i_attstorage; int i_attstorage;
int i_typstorage; int i_typstorage;
int i_attnotnull; int i_attnotnull;
...@@ -4752,11 +4753,28 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4752,11 +4753,28 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
resetPQExpBuffer(q); resetPQExpBuffer(q);
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 80500)
{
/* attdistinct is new in 8.5 */
appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
"a.attstattarget, a.attdistinct, "
"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 "
"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 "
"AND a.attnum > 0::pg_catalog.int2 "
"ORDER BY a.attrelid, a.attnum",
tbinfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 70300)
{ {
/* need left join here to not fail on dropped columns ... */ /* need left join here to not fail on dropped columns ... */
appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
"a.attstattarget, a.attstorage, t.typstorage, " "a.attstattarget, 0 AS attdistinct, "
"a.attstorage, t.typstorage, "
"a.attnotnull, a.atthasdef, a.attisdropped, " "a.attnotnull, a.atthasdef, a.attisdropped, "
"a.attlen, a.attalign, a.attislocal, " "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 "
...@@ -4774,8 +4792,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4774,8 +4792,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
* we don't dump it because we can't tell whether it's been * we don't dump it because we can't tell whether it's been
* explicitly set or was just a default. * explicitly set or was just a default.
*/ */
appendPQExpBuffer(q, "SELECT a.attnum, a.attname, " appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
"a.atttypmod, -1 AS attstattarget, a.attstorage, " "-1 AS attstattarget, 0 AS attdistinct, "
"a.attstorage, "
"t.typstorage, a.attnotnull, a.atthasdef, " "t.typstorage, a.attnotnull, a.atthasdef, "
"false AS attisdropped, a.attlen, " "false AS attisdropped, a.attlen, "
"a.attalign, false AS attislocal, " "a.attalign, false AS attislocal, "
...@@ -4791,8 +4810,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4791,8 +4810,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{ {
/* format_type not available before 7.1 */ /* format_type not available before 7.1 */
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, " appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, "
"-1 AS attstattarget, attstorage, " "-1 AS attstattarget, 0 AS attdistinct, "
"attstorage AS typstorage, " "attstorage, attstorage AS typstorage, "
"attnotnull, atthasdef, false AS attisdropped, " "attnotnull, atthasdef, false AS attisdropped, "
"attlen, attalign, " "attlen, attalign, "
"false AS attislocal, " "false AS attislocal, "
...@@ -4814,6 +4833,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4814,6 +4833,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
i_atttypname = PQfnumber(res, "atttypname"); i_atttypname = PQfnumber(res, "atttypname");
i_atttypmod = PQfnumber(res, "atttypmod"); i_atttypmod = PQfnumber(res, "atttypmod");
i_attstattarget = PQfnumber(res, "attstattarget"); i_attstattarget = PQfnumber(res, "attstattarget");
i_attdistinct = PQfnumber(res, "attdistinct");
i_attstorage = PQfnumber(res, "attstorage"); i_attstorage = PQfnumber(res, "attstorage");
i_typstorage = PQfnumber(res, "typstorage"); i_typstorage = PQfnumber(res, "typstorage");
i_attnotnull = PQfnumber(res, "attnotnull"); i_attnotnull = PQfnumber(res, "attnotnull");
...@@ -4828,6 +4848,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4828,6 +4848,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tbinfo->atttypnames = (char **) malloc(ntups * sizeof(char *)); tbinfo->atttypnames = (char **) malloc(ntups * sizeof(char *));
tbinfo->atttypmod = (int *) malloc(ntups * sizeof(int)); tbinfo->atttypmod = (int *) malloc(ntups * sizeof(int));
tbinfo->attstattarget = (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->attstorage = (char *) malloc(ntups * sizeof(char));
tbinfo->typstorage = (char *) malloc(ntups * sizeof(char)); tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool)); tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
...@@ -4853,6 +4874,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -4853,6 +4874,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tbinfo->atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname)); tbinfo->atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname));
tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod)); tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget)); 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->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage)); tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't'); tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
...@@ -10189,6 +10212,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) ...@@ -10189,6 +10212,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
tbinfo->attstattarget[j]); 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 * Dump per-column storage information. The statement is only
* dumped if the storage has been changed from the type's default. * dumped if the storage has been changed from the type's default.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.155 2009/07/29 20:56:19 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.156 2009/08/02 22:14:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -243,6 +243,7 @@ typedef struct _tableInfo ...@@ -243,6 +243,7 @@ typedef struct _tableInfo
char **atttypnames; /* attribute type names */ char **atttypnames; /* attribute type names */
int *atttypmod; /* type-specific type modifiers */ int *atttypmod; /* type-specific type modifiers */
int *attstattarget; /* attribute statistics targets */ int *attstattarget; /* attribute statistics targets */
float4 *attdistinct; /* override ndistinct calculation */
char *attstorage; /* attribute storage scheme */ char *attstorage; /* attribute storage scheme */
char *typstorage; /* type storage scheme */ char *typstorage; /* type storage scheme */
bool *attisdropped; /* true if attr is dropped; don't dump it */ bool *attisdropped; /* true if attr is dropped; don't dump it */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.184 2009/06/11 14:49:08 momjian Exp $ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.185 2009/08/02 22:14:52 tgl Exp $
*/ */
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
...@@ -674,12 +674,10 @@ psql_completion(char *text, int start, int end) ...@@ -674,12 +674,10 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "CREATE") == 0) else if (pg_strcasecmp(prev_wd, "CREATE") == 0)
matches = completion_matches(text, create_command_generator); matches = completion_matches(text, create_command_generator);
/* DROP, except ALTER (TABLE|DOMAIN|GROUP) sth DROP */ /* DROP, but watch out for DROP embedded in other commands */
/* complete with something you can drop */ /* complete with something you can drop */
else if (pg_strcasecmp(prev_wd, "DROP") == 0 && else if (pg_strcasecmp(prev_wd, "DROP") == 0 &&
pg_strcasecmp(prev3_wd, "TABLE") != 0 && pg_strcasecmp(prev2_wd, "DROP") == 0)
pg_strcasecmp(prev3_wd, "DOMAIN") != 0 &&
pg_strcasecmp(prev3_wd, "GROUP") != 0)
matches = completion_matches(text, drop_command_generator); matches = completion_matches(text, drop_command_generator);
/* ALTER */ /* ALTER */
...@@ -967,13 +965,44 @@ psql_completion(char *text, int start, int end) ...@@ -967,13 +965,44 @@ psql_completion(char *text, int start, int end)
(pg_strcasecmp(prev4_wd, "TABLE") == 0 && (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
pg_strcasecmp(prev2_wd, "ALTER") == 0)) pg_strcasecmp(prev2_wd, "ALTER") == 0))
{ {
/* DROP ... does not work well yet */
static const char *const list_COLUMNALTER[] = static const char *const list_COLUMNALTER[] =
{"TYPE", "SET DEFAULT", "DROP DEFAULT", "SET NOT NULL", {"TYPE", "SET", "DROP", NULL};
"DROP NOT NULL", "SET STATISTICS", "SET STORAGE", NULL};
COMPLETE_WITH_LIST(list_COLUMNALTER); COMPLETE_WITH_LIST(list_COLUMNALTER);
} }
else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
(pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
pg_strcasecmp(prev3_wd, "ALTER") == 0)) &&
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_COLUMNSET[] =
{"DEFAULT", "NOT NULL", "STATISTICS", "STORAGE", NULL};
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 &&
pg_strcasecmp(prev3_wd, "ALTER") == 0)) &&
pg_strcasecmp(prev_wd, "DROP") == 0)
{
static const char *const list_COLUMNDROP[] =
{"DEFAULT", "NOT NULL", NULL};
COMPLETE_WITH_LIST(list_COLUMNDROP);
}
else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
pg_strcasecmp(prev_wd, "CLUSTER") == 0) pg_strcasecmp(prev_wd, "CLUSTER") == 0)
COMPLETE_WITH_CONST("ON"); COMPLETE_WITH_CONST("ON");
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.534 2009/07/29 20:56:19 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.535 2009/08/02 22:14:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200907291 #define CATALOG_VERSION_NO 200908021
#endif #endif
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.114 2009/06/11 14:49:09 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.115 2009/08/02 22:14:53 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -125,7 +125,7 @@ typedef FormData_pg_class *Form_pg_class; ...@@ -125,7 +125,7 @@ typedef FormData_pg_class *Form_pg_class;
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f f r 28 0 t f f f f 3 _null_ _null_ )); DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f f r 28 0 t f f f f 3 _null_ _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f f r 18 0 f f f f f 3 _null_ _null_ )); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f f r 19 0 f f f f f 3 _null_ _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f f r 25 0 t f f f f 3 _null_ _null_ )); DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f f r 25 0 t f f f f 3 _null_ _null_ ));
DESCR(""); DESCR("");
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.400 2009/07/30 02:45:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.401 2009/08/02 22:14:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1098,8 +1098,9 @@ typedef enum AlterTableType ...@@ -1098,8 +1098,9 @@ typedef enum AlterTableType
AT_ColumnDefault, /* alter column default */ AT_ColumnDefault, /* alter column default */
AT_DropNotNull, /* alter column drop not null */ AT_DropNotNull, /* alter column drop not null */
AT_SetNotNull, /* alter column set not null */ AT_SetNotNull, /* alter column set not null */
AT_SetStatistics, /* alter column statistics */ AT_SetStatistics, /* alter column set statistics */
AT_SetStorage, /* alter column storage */ AT_SetDistinct, /* alter column set statistics distinct */
AT_SetStorage, /* alter column set storage */
AT_DropColumn, /* drop column */ AT_DropColumn, /* drop column */
AT_DropColumnRecurse, /* internal to commands/tablecmds.c */ AT_DropColumnRecurse, /* internal to commands/tablecmds.c */
AT_AddIndex, /* add index */ AT_AddIndex, /* add index */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment