Skip to content

Commit 76a47c0

Browse files
committed
Replace ALTER TABLE ... SET STATISTICS DISTINCT with a more general mechanism.
Attributes can now have options, just as relations and tablespaces do, and the reloptions code is used to parse, validate, and store them. For simplicity and because these options are not performance critical, we store them in a separate cache rather than the main relcache. Thanks to Alex Hunsaker for the review.
1 parent 9ca0989 commit 76a47c0

File tree

19 files changed

+267
-223
lines changed

19 files changed

+267
-223
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.218 2010/01/17 22:56:21 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.219 2010/01/22 16:40:18 rhaas Exp $ -->
22
<!--
33
Documentation of the system catalogs, directed toward PostgreSQL developers
44
-->
@@ -901,19 +901,6 @@
901901
</entry>
902902
</row>
903903

904-
<row>
905-
<entry><structfield>attdistinct</structfield></entry>
906-
<entry><type>float4</type></entry>
907-
<entry></entry>
908-
<entry>
909-
<structfield>attdistinct</structfield>, if nonzero, is a user-specified
910-
number-of-distinct-values figure to be used instead of estimating the
911-
number of distinct values during <command>ANALYZE</>. Nonzero values
912-
have the same meanings as for
913-
<link linkend="catalog-pg-statistic"><structname>pg_statistic</></link>.<structfield>stadistinct</>
914-
</entry>
915-
</row>
916-
917904
<row>
918905
<entry><structfield>attlen</structfield></entry>
919906
<entry><type>int2</type></entry>
@@ -1061,6 +1048,15 @@
10611048
</entry>
10621049
</row>
10631050

1051+
<row>
1052+
<entry><structfield>attoptions</structfield></entry>
1053+
<entry><type>text[]</type></entry>
1054+
<entry></entry>
1055+
<entry>
1056+
Attribute-level options, as <quote>keyword=value</> strings
1057+
</entry>
1058+
</row>
1059+
10641060
</tbody>
10651061
</tgroup>
10661062
</table>

doc/src/sgml/ref/alter_table.sgml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.109 2009/09/18 05:00:41 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.110 2010/01/22 16:40:18 rhaas Exp $
33
PostgreSQL documentation
44
-->
55

@@ -39,7 +39,8 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
3939
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> DROP DEFAULT
4040
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
4141
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
42-
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS DISTINCT <replaceable class="PARAMETER">number</replaceable>
42+
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
43+
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )
4344
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
4445
ADD <replaceable class="PARAMETER">table_constraint</replaceable>
4546
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
@@ -158,14 +159,21 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
158159
</varlistentry>
159160

160161
<varlistentry>
161-
<term><literal>SET STATISTICS DISTINCT</literal></term>
162+
<term><literal>SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )</term></literal>
163+
<term><literal>RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )</literal>
162164
<listitem>
163165
<para>
164-
This form overrides the number-of-distinct-values estimate made by
165-
subsequent <xref linkend="sql-analyze" endterm="sql-analyze-title">
166-
operations. When set to a positive value, <command>ANALYZE</> will
167-
assume that the column contains exactly the specified number of distinct
168-
nonnull values. When set to a negative value, which must be greater
166+
This form sets or resets attribute-level options. Currently, the only
167+
define attribute-level options are <literal>n_distinct</> and
168+
<literal>n_distinct_inherited</>, which override the
169+
number-of-distinct-values estimate made by subsequent
170+
<xref linkend="sql-analyze" endterm="sql-analyze-title">
171+
operations. <literal>n_distinct</> affects the statistics for the table
172+
itself, while <literal>n_distinct_inherited</> affects the statistics
173+
gathered for the table and its inheritance children. When set to a
174+
positive value, <command>ANALYZE</> will assume that the column contains
175+
exactly the specified number of distinct nonnull values. When set to a
176+
negative value, which must be greater
169177
than or equal to -1, <command>ANALYZE</> will assume that the number of
170178
distinct nonnull values in the column is linear in the size of the
171179
table; the exact count is to be computed by multiplying the estimated

doc/src/sgml/ref/analyze.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.27 2009/08/04 22:04:37 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/analyze.sgml,v 1.28 2010/01/22 16:40:18 rhaas Exp $
33
PostgreSQL documentation
44
-->
55

@@ -173,7 +173,7 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> [ ( <re
173173
with the largest possible statistics target. If this inaccuracy leads to
174174
bad query plans, a more accurate value can be determined manually and then
175175
installed with
176-
<command>ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT</>
176+
<command>ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)</>
177177
(see <xref linkend="sql-altertable" endterm="sql-altertable-title">).
178178
</para>
179179
</refsect1>

src/backend/access/common/reloptions.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.31 2010/01/05 21:53:58 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.32 2010/01/22 16:40:18 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -24,6 +24,7 @@
2424
#include "commands/tablespace.h"
2525
#include "nodes/makefuncs.h"
2626
#include "utils/array.h"
27+
#include "utils/attoptcache.h"
2728
#include "utils/builtins.h"
2829
#include "utils/guc.h"
2930
#include "utils/memutils.h"
@@ -196,6 +197,22 @@ static relopt_real realRelOpts[] =
196197
},
197198
-1, 0.0, DBL_MAX
198199
},
200+
{
201+
{
202+
"n_distinct",
203+
"Sets the planner's estimate of the number of distinct values appearing in a column (excluding child relations).",
204+
RELOPT_KIND_ATTRIBUTE
205+
},
206+
0, -1.0, DBL_MAX
207+
},
208+
{
209+
{
210+
"n_distinct_inherited",
211+
"Sets the planner's estimate of the number of distinct values appearing in a column (including child relations).",
212+
RELOPT_KIND_ATTRIBUTE
213+
},
214+
0, -1.0, DBL_MAX
215+
},
199216
/* list terminator */
200217
{{NULL}}
201218
};
@@ -1186,6 +1203,37 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate)
11861203
return DatumGetByteaP(result);
11871204
}
11881205

1206+
/*
1207+
* Option parser for attribute reloptions
1208+
*/
1209+
bytea *
1210+
attribute_reloptions(Datum reloptions, bool validate)
1211+
{
1212+
relopt_value *options;
1213+
AttributeOpts *aopts;
1214+
int numoptions;
1215+
static const relopt_parse_elt tab[] = {
1216+
{"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
1217+
{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
1218+
};
1219+
1220+
options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
1221+
&numoptions);
1222+
1223+
/* if none set, we're done */
1224+
if (numoptions == 0)
1225+
return NULL;
1226+
1227+
aopts = allocateReloptStruct(sizeof(AttributeOpts), options, numoptions);
1228+
1229+
fillRelOptions((void *) aopts, sizeof(AttributeOpts), options, numoptions,
1230+
validate, tab, lengthof(tab));
1231+
1232+
pfree(options);
1233+
1234+
return (bytea *) aopts;
1235+
}
1236+
11891237
/*
11901238
* Option parser for tablespace reloptions
11911239
*/

src/backend/access/common/tupdesc.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.131 2010/01/02 16:57:33 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.132 2010/01/22 16:40:18 rhaas Exp $
1212
*
1313
* NOTES
1414
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -338,8 +338,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
338338
return false;
339339
if (attr1->attstattarget != attr2->attstattarget)
340340
return false;
341-
if (attr1->attdistinct != attr2->attdistinct)
342-
return false;
343341
if (attr1->attlen != attr2->attlen)
344342
return false;
345343
if (attr1->attndims != attr2->attndims)
@@ -362,7 +360,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
362360
return false;
363361
if (attr1->attinhcount != attr2->attinhcount)
364362
return false;
365-
/* attacl is ignored, since it's not even present... */
363+
/* attacl and attoptions are not even present... */
366364
}
367365

368366
if (tupdesc1->constr != NULL)
@@ -467,7 +465,6 @@ TupleDescInitEntry(TupleDesc desc,
467465
MemSet(NameStr(att->attname), 0, NAMEDATALEN);
468466

469467
att->attstattarget = -1;
470-
att->attdistinct = 0;
471468
att->attcacheoff = -1;
472469
att->atttypmod = typmod;
473470

@@ -479,7 +476,7 @@ TupleDescInitEntry(TupleDesc desc,
479476
att->attisdropped = false;
480477
att->attislocal = true;
481478
att->attinhcount = 0;
482-
/* attacl is not set because it's not present in tupledescs */
479+
/* attacl and attoptions are not present in tupledescs */
483480

484481
tuple = SearchSysCache(TYPEOID,
485482
ObjectIdGetDatum(oidtypeid),

src/backend/bootstrap/bootstrap.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.257 2010/01/20 09:16:23 heikki Exp $
11+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.258 2010/01/22 16:40:18 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -737,7 +737,6 @@ DefineAttr(char *name, char *type, int attnum)
737737
}
738738

739739
attrtypes[attnum]->attstattarget = -1;
740-
attrtypes[attnum]->attdistinct = 0;
741740
attrtypes[attnum]->attcacheoff = -1;
742741
attrtypes[attnum]->atttypmod = -1;
743742
attrtypes[attnum]->attislocal = true;

src/backend/catalog/genbki.pl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
1111
# Portions Copyright (c) 1994, Regents of the University of California
1212
#
13-
# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.6 2010/01/06 22:02:45 tgl Exp $
13+
# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.7 2010/01/22 16:40:18 rhaas Exp $
1414
#
1515
#----------------------------------------------------------------------
1616

@@ -200,7 +200,8 @@
200200
# Store schemapg entries for later.
201201
$row = emit_schemapg_row($row, grep { $bki_attr{$_} eq 'bool' } @attnames);
202202
push @{ $schemapg_entries{$table_name} },
203-
'{ ' . join(', ', map $row->{$_}, @attnames) . ' }';
203+
'{ ' . join(', ', grep { defined $_ }
204+
map $row->{$_}, @attnames) . ' }';
204205
}
205206

206207
# Generate entries for system attributes.
@@ -351,14 +352,14 @@ sub emit_pgattr_row
351352

352353
# Add in default values for pg_attribute
353354
my %PGATTR_DEFAULTS = (
354-
attdistinct => '0',
355355
attcacheoff => '-1',
356356
atttypmod => '-1',
357357
atthasdef => 'f',
358358
attisdropped => 'f',
359359
attislocal => 't',
360360
attinhcount => '0',
361-
attacl => '_null_'
361+
attacl => '_null_',
362+
attoptions => '_null_'
362363
);
363364
return {%PGATTR_DEFAULTS, %row};
364365
}
@@ -384,7 +385,11 @@ sub emit_schemapg_row
384385
$row->{attname} = q|{"| . $row->{attname} . q|"}|;
385386
$row->{attstorage} = q|'| . $row->{attstorage} . q|'|;
386387
$row->{attalign} = q|'| . $row->{attalign} . q|'|;
387-
$row->{attacl} = q|{ 0 }|;
388+
389+
# We don't emit initializers for the variable length fields at all.
390+
# Only the fixed-size portions of the descriptors are ever used.
391+
delete $row->{attacl};
392+
delete $row->{attoptions};
388393

389394
# Expand booleans from 'f'/'t' to 'false'/'true'.
390395
# Some values might be other macros (eg FLOAT4PASSBYVAL), don't change.

0 commit comments

Comments
 (0)