Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
90725929
Commit
90725929
authored
Aug 02, 2009
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT
Robert Haas
parent
527f0ae3
Changes
17
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
562 additions
and
305 deletions
+562
-305
doc/src/sgml/catalogs.sgml
doc/src/sgml/catalogs.sgml
+18
-4
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/alter_table.sgml
+29
-3
doc/src/sgml/ref/analyze.sgml
doc/src/sgml/ref/analyze.sgml
+12
-1
src/backend/access/common/tupdesc.c
src/backend/access/common/tupdesc.c
+4
-1
src/backend/bootstrap/bootstrap.c
src/backend/bootstrap/bootstrap.c
+2
-1
src/backend/catalog/heap.c
src/backend/catalog/heap.c
+10
-8
src/backend/catalog/index.c
src/backend/catalog/index.c
+2
-1
src/backend/commands/analyze.c
src/backend/commands/analyze.c
+9
-1
src/backend/commands/tablecmds.c
src/backend/commands/tablecmds.c
+109
-7
src/backend/parser/gram.y
src/backend/parser/gram.y
+10
-1
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.c
+46
-7
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dump.h
+2
-1
src/bin/psql/tab-complete.c
src/bin/psql/tab-complete.c
+37
-8
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/pg_attribute.h
src/include/catalog/pg_attribute.h
+264
-254
src/include/catalog/pg_class.h
src/include/catalog/pg_class.h
+2
-2
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+4
-3
No files found.
doc/src/sgml/catalogs.sgml
View file @
90725929
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.20
3 2009/07/29 20:56:17
tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.20
4 2009/08/02 22:14:51
tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
...
...
@@ -886,6 +886,19 @@
</entry>
</row>
<row>
<entry><structfield>attdistinct</structfield></entry>
<entry><type>float4</type></entry>
<entry></entry>
<entry>
<structfield>attdistinct</structfield>, if nonzero, is a user-specified
number-of-distinct-values figure to be used instead of estimating the
number of distinct values during <command>ANALYZE</>. Nonzero values
have the same meanings as for
<link linkend="catalog-pg-statistic"><structname>pg_statistic</></link>.<structfield>stadistinct</>
</entry>
</row>
<row>
<entry><structfield>attlen</structfield></entry>
<entry><type>int2</type></entry>
...
...
@@ -4303,9 +4316,10 @@
<entry></entry>
<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 less than zero is the negative of a fraction of the number
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).
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
twice on the average could be represented by
<structfield>stadistinct</> = -0.5.
A zero value means the number of distinct values is unknown
</entry>
</row>
...
...
doc/src/sgml/ref/alter_table.sgml
View file @
90725929
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.10
7 2009/07/20 02:42:27 adunstan
Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.10
8 2009/08/02 22:14:51 tgl
Exp $
PostgreSQL documentation
-->
...
...
@@ -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> { SET | DROP } NOT NULL
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS DISTINCT <replaceable class="PARAMETER">number</replaceable>
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD <replaceable class="PARAMETER">table_constraint</replaceable>
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
...
...
@@ -156,6 +157,31 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</listitem>
</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>
<indexterm>
<primary>TOAST</primary>
...
...
doc/src/sgml/ref/analyze.sgml
View file @
90725929
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.2
5 2008/12/13 19:13:44
tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.2
6 2009/08/02 22:14:51
tgl Exp $
PostgreSQL documentation
-->
...
...
@@ -165,6 +165,17 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
the target causes a proportional increase in the time and space needed
to do <command>ANALYZE</command>.
</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>
...
...
src/backend/access/common/tupdesc.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.12
7 2009/07/16 06:33:42 petere
Exp $
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.12
8 2009/08/02 22:14:51 tgl
Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
...
...
@@ -338,6 +338,8 @@ 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
)
...
...
@@ -465,6 +467,7 @@ TupleDescInitEntry(TupleDesc desc,
MemSet
(
NameStr
(
att
->
attname
),
0
,
NAMEDATALEN
);
att
->
attstattarget
=
-
1
;
att
->
attdistinct
=
0
;
att
->
attcacheoff
=
-
1
;
att
->
atttypmod
=
typmod
;
...
...
src/backend/bootstrap/bootstrap.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.25
1 2009/07/31 20:26:22
tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.25
2 2009/08/02 22:14:51
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -757,6 +757,7 @@ 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
;
...
...
src/backend/catalog/heap.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.35
6 2009/07/30 02:45:36
tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.35
7 2009/08/02 22:14:52
tgl Exp $
*
*
* INTERFACE ROUTINES
...
...
@@ -111,37 +111,37 @@ static List *insert_ordered_unique_oid(List *list, Oid datum);
*/
static
FormData_pg_attribute
a1
=
{
0
,
{
"ctid"
},
TIDOID
,
0
,
sizeof
(
ItemPointerData
),
0
,
{
"ctid"
},
TIDOID
,
0
,
0
,
sizeof
(
ItemPointerData
),
SelfItemPointerAttributeNumber
,
0
,
-
1
,
-
1
,
false
,
'p'
,
's'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
static
FormData_pg_attribute
a2
=
{
0
,
{
"oid"
},
OIDOID
,
0
,
sizeof
(
Oid
),
0
,
{
"oid"
},
OIDOID
,
0
,
0
,
sizeof
(
Oid
),
ObjectIdAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
static
FormData_pg_attribute
a3
=
{
0
,
{
"xmin"
},
XIDOID
,
0
,
sizeof
(
TransactionId
),
0
,
{
"xmin"
},
XIDOID
,
0
,
0
,
sizeof
(
TransactionId
),
MinTransactionIdAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
static
FormData_pg_attribute
a4
=
{
0
,
{
"cmin"
},
CIDOID
,
0
,
sizeof
(
CommandId
),
0
,
{
"cmin"
},
CIDOID
,
0
,
0
,
sizeof
(
CommandId
),
MinCommandIdAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
static
FormData_pg_attribute
a5
=
{
0
,
{
"xmax"
},
XIDOID
,
0
,
sizeof
(
TransactionId
),
0
,
{
"xmax"
},
XIDOID
,
0
,
0
,
sizeof
(
TransactionId
),
MaxTransactionIdAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
static
FormData_pg_attribute
a6
=
{
0
,
{
"cmax"
},
CIDOID
,
0
,
sizeof
(
CommandId
),
0
,
{
"cmax"
},
CIDOID
,
0
,
0
,
sizeof
(
CommandId
),
MaxCommandIdAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
...
...
@@ -153,7 +153,7 @@ static FormData_pg_attribute a6 = {
* used in SQL.
*/
static
FormData_pg_attribute
a7
=
{
0
,
{
"tableoid"
},
OIDOID
,
0
,
sizeof
(
Oid
),
0
,
{
"tableoid"
},
OIDOID
,
0
,
0
,
sizeof
(
Oid
),
TableOidAttributeNumber
,
0
,
-
1
,
-
1
,
true
,
'p'
,
'i'
,
true
,
false
,
false
,
true
,
0
,
{
0
}
};
...
...
@@ -501,6 +501,7 @@ 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
);
...
...
@@ -571,6 +572,7 @@ 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
);
...
...
src/backend/catalog/index.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.32
0 2009/07/29 20:56:18
tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.32
1 2009/08/02 22:14:52
tgl Exp $
*
*
* INTERFACE ROUTINES
...
...
@@ -192,6 +192,7 @@ ConstructTupleDescriptor(Relation heapRelation,
to
->
attnum
=
i
+
1
;
to
->
attstattarget
=
-
1
;
to
->
attdistinct
=
0
;
to
->
attcacheoff
=
-
1
;
to
->
attnotnull
=
false
;
to
->
atthasdef
=
false
;
...
...
src/backend/commands/analyze.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.1
39 2009/06/11 14:48:55 momjian
Exp $
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.1
40 2009/08/02 22:14:52 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -425,6 +425,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
std_fetch_func
,
numrows
,
totalrows
);
/* If attdistinct is set, override with that value */
if
(
stats
->
attr
->
attdistinct
!=
0
)
stats
->
stadistinct
=
stats
->
attr
->
attdistinct
;
MemoryContextResetAndDeleteChildren
(
col_context
);
}
...
...
@@ -679,6 +684,9 @@ 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
;
MemoryContextResetAndDeleteChildren
(
col_context
);
}
}
...
...
src/backend/commands/tablecmds.c
View file @
90725929
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.29
4 2009/07/30 02:45:36
tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.29
5 2009/08/02 22:14:52
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -280,9 +280,13 @@ static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
static
void
ATExecColumnDefault
(
Relation
rel
,
const
char
*
colName
,
Node
*
newDefault
);
static
void
ATPrepSetStatistics
(
Relation
rel
,
const
char
*
colName
,
Node
*
flag
Value
);
Node
*
new
Value
);
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
ATExecSetStorage
(
Relation
rel
,
const
char
*
colName
,
Node
*
newValue
);
static
void
ATExecDropColumn
(
List
**
wqueue
,
Relation
rel
,
const
char
*
colName
,
...
...
@@ -2399,13 +2403,19 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
/* No command-specific prep needed */
pass
=
AT_PASS_ADD_CONSTR
;
break
;
case
AT_SetStatistics
:
/* ALTER COLUMN STATISTICS */
case
AT_SetStatistics
:
/* ALTER COLUMN S
ET S
TATISTICS */
ATSimpleRecursion
(
wqueue
,
rel
,
cmd
,
recurse
);
/* Performs own permission checks */
ATPrepSetStatistics
(
rel
,
cmd
->
name
,
cmd
->
def
);
pass
=
AT_PASS_COL_ATTRS
;
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
);
ATSimpleRecursion
(
wqueue
,
rel
,
cmd
,
recurse
);
/* No command-specific prep needed */
...
...
@@ -2616,10 +2626,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
case
AT_SetNotNull
:
/* ALTER COLUMN SET NOT NULL */
ATExecSetNotNull
(
tab
,
rel
,
cmd
->
name
);
break
;
case
AT_SetStatistics
:
/* ALTER COLUMN STATISTICS */
case
AT_SetStatistics
:
/* ALTER COLUMN S
ET S
TATISTICS */
ATExecSetStatistics
(
rel
,
cmd
->
name
,
cmd
->
def
);
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
);
break
;
case
AT_DropColumn
:
/* DROP COLUMN */
...
...
@@ -3620,6 +3633,7 @@ 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
;
...
...
@@ -4007,7 +4021,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
* ALTER TABLE ALTER COLUMN SET STATISTICS
*/
static
void
ATPrepSetStatistics
(
Relation
rel
,
const
char
*
colName
,
Node
*
flag
Value
)
ATPrepSetStatistics
(
Relation
rel
,
const
char
*
colName
,
Node
*
new
Value
)
{
/*
* 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)
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
*/
...
...
src/backend/parser/gram.y
View file @
90725929
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.67
5 2009/07/30 02:45:37
tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.67
6 2009/08/02 22:14:52
tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -1605,6 +1605,15 @@ 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
{
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 opt_column ColId SET STORAGE ColId
{
...
...
src/bin/pg_dump/pg_dump.c
View file @
90725929
...
...
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.54
3 2009/07/29 20:56:19
tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.54
4 2009/08/02 22:14:52
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -4707,6 +4707,7 @@ 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
;
...
...
@@ -4752,11 +4753,28 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
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 ... */
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.attlen, a.attalign, a.attislocal, "
"pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname "
...
...
@@ -4774,8 +4792,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
* we don't dump it because we can't tell whether it's been
* explicitly set or was just a default.
*/
appendPQExpBuffer
(
q
,
"SELECT a.attnum, a.attname, "
"a.atttypmod, -1 AS attstattarget, a.attstorage, "
appendPQExpBuffer
(
q
,
"SELECT a.attnum, a.attname, a.atttypmod, "
"-1 AS attstattarget, 0 AS attdistinct, "
"a.attstorage, "
"t.typstorage, a.attnotnull, a.atthasdef, "
"false AS attisdropped, a.attlen, "
"a.attalign, false AS attislocal, "
...
...
@@ -4791,8 +4810,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{
/* format_type not available before 7.1 */
appendPQExpBuffer
(
q
,
"SELECT attnum, attname, atttypmod, "
"-1 AS attstattarget,
attstorage
, "
"attstorage AS typstorage, "
"-1 AS attstattarget,
0 AS attdistinct
, "
"attstorage
, attstorage
AS typstorage, "
"attnotnull, atthasdef, false AS attisdropped, "
"attlen, attalign, "
"false AS attislocal, "
...
...
@@ -4814,6 +4833,7 @@ 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"
);
...
...
@@ -4828,6 +4848,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
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
));
...
...
@@ -4853,6 +4874,8 @@ 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'
);
...
...
@@ -10189,6 +10212,22 @@ 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.
...
...
src/bin/pg_dump/pg_dump.h
View file @
90725929
...
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, 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.15
5 2009/07/29 20:56:19
tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.15
6 2009/08/02 22:14:52
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -243,6 +243,7 @@ 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 */
...
...
src/bin/psql/tab-complete.c
View file @
90725929
...
...
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.18
4 2009/06/11 14:49:08 momjian
Exp $
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.18
5 2009/08/02 22:14:52 tgl
Exp $
*/
/*----------------------------------------------------------------------
...
...
@@ -674,12 +674,10 @@ psql_completion(char *text, int start, int end)
else
if
(
pg_strcasecmp
(
prev_wd
,
"CREATE"
)
==
0
)
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 */
else
if
(
pg_strcasecmp
(
prev_wd
,
"DROP"
)
==
0
&&
pg_strcasecmp
(
prev3_wd
,
"TABLE"
)
!=
0
&&
pg_strcasecmp
(
prev3_wd
,
"DOMAIN"
)
!=
0
&&
pg_strcasecmp
(
prev3_wd
,
"GROUP"
)
!=
0
)
pg_strcasecmp
(
prev2_wd
,
"DROP"
)
==
0
)
matches
=
completion_matches
(
text
,
drop_command_generator
);
/* ALTER */
...
...
@@ -967,13 +965,44 @@ psql_completion(char *text, int start, int end)
(
pg_strcasecmp
(
prev4_wd
,
"TABLE"
)
==
0
&&
pg_strcasecmp
(
prev2_wd
,
"ALTER"
)
==
0
))
{
/* DROP ... does not work well yet */
static
const
char
*
const
list_COLUMNALTER
[]
=
{
"TYPE"
,
"SET DEFAULT"
,
"DROP DEFAULT"
,
"SET NOT NULL"
,
"DROP NOT NULL"
,
"SET STATISTICS"
,
"SET STORAGE"
,
NULL
};
{
"TYPE"
,
"SET"
,
"DROP"
,
NULL
};
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
&&
pg_strcasecmp
(
prev_wd
,
"CLUSTER"
)
==
0
)
COMPLETE_WITH_CONST
(
"ON"
);
...
...
src/include/catalog/catversion.h
View file @
90725929
...
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.53
4 2009/07/29 20:56:19
tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.53
5 2009/08/02 22:14:52
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 20090
729
1
#define CATALOG_VERSION_NO 20090
802
1
#endif
src/include/catalog/pg_attribute.h
View file @
90725929
This diff is collapsed.
Click to expand it.
src/include/catalog/pg_class.h
View file @
90725929
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.11
4 2009/06/11 14:49:09 momjian
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.11
5 2009/08/02 22:14:53 tgl
Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -125,7 +125,7 @@ typedef FormData_pg_class *Form_pg_class;
/* 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_
));
DESCR
(
""
);
DATA
(
insert
OID
=
1249
(
pg_attribute
PGNSP
75
PGUID
0
1249
0
0
0
0
0
f
f
f
r
1
8
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
1
9
0
f
f
f
f
f
3
_null_
_null_
));
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_
));
DESCR
(
""
);
...
...
src/include/nodes/parsenodes.h
View file @
90725929
...
...
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.40
0 2009/07/30 02:45:38
tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.40
1 2009/08/02 22:14:53
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1098,8 +1098,9 @@ typedef enum AlterTableType
AT_ColumnDefault
,
/* alter column default */
AT_DropNotNull
,
/* alter column drop not null */
AT_SetNotNull
,
/* alter column set not null */
AT_SetStatistics
,
/* alter column statistics */
AT_SetStorage
,
/* alter column storage */
AT_SetStatistics
,
/* alter column set statistics */
AT_SetDistinct
,
/* alter column set statistics distinct */
AT_SetStorage
,
/* alter column set storage */
AT_DropColumn
,
/* drop column */
AT_DropColumnRecurse
,
/* internal to commands/tablecmds.c */
AT_AddIndex
,
/* add index */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment