Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf31dc0a

Browse files
committed
Partial indexes work again, courtesy of Martijn van Oosterhout.
Note: I didn't force an initdb, figuring that one today was enough.However, there is a new function in pg_proc.h, and pg_dump won't beable to dump partial indexes until you add that function.
1 parent237e5df commitf31dc0a

File tree

32 files changed

+469
-486
lines changed

32 files changed

+469
-486
lines changed

‎doc/src/sgml/indices.sgml

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.19 2001/05/30 04:01:11 momjian Exp $ -->
1+
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.20 2001/07/16 05:06:57 tgl Exp $ -->
22

33
<chapter id="indexes">
44
<title id="indexes-title">Indexes</title>
@@ -603,22 +603,11 @@ CREATE MEMSTORE ON <replaceable>table</replaceable> COLUMNS <replaceable>cols</r
603603
</para>
604604
</note>
605605

606-
<note>
607-
<title>Note</title>
608-
<para>
609-
Partial indexes are not currently supported by
610-
<productname>PostgreSQL</productname>, but they were once supported
611-
by its predecessor <productname>Postgres</productname>, and much
612-
of the code is still there. We hope to revive support for this
613-
feature someday.
614-
</para>
615-
</note>
616-
617606
<para>
618607
A <firstterm>partial index</firstterm>
619608
is an index built over a subset of a table; the subset is defined by
620609
a predicate. <productname>Postgres</productname>
621-
supported partial indexes with arbitrary
610+
supports partial indexes with arbitrary
622611
predicates. I believe IBM's <productname>DB2</productname>
623612
for AS/400 supports partial indexes
624613
using single-clause predicates.

‎doc/src/sgml/ref/create_index.sgml

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_index.sgml,v 1.19 2001/05/17 21:50:18 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_index.sgml,v 1.20 2001/07/16 05:06:57 tgl Exp $
33
Postgres documentation
44
-->
55

@@ -20,13 +20,15 @@ Postgres documentation
2020
</refnamediv>
2121
<refsynopsisdiv>
2222
<refsynopsisdivinfo>
23-
<date>1999-07-20</date>
23+
<date>2001-07-15</date>
2424
</refsynopsisdivinfo>
2525
<synopsis>
2626
CREATE [ UNIQUE ] INDEX <replaceable class="parameter">index_name</replaceable> ON <replaceable class="parameter">table</replaceable>
27-
[ USING <replaceable class="parameter">acc_name</replaceable> ] ( <replaceable class="parameter">column</replaceable> [ <replaceable class="parameter">ops_name</replaceable> ] [, ...] )
27+
[ USING <replaceable class="parameter">acc_method</replaceable> ] ( <replaceable class="parameter">column</replaceable> [ <replaceable class="parameter">ops_name</replaceable> ] [, ...] )
28+
[ WHERE <replaceable class="parameter">predicate</replaceable> ]
2829
CREATE [ UNIQUE ] INDEX <replaceable class="parameter">index_name</replaceable> ON <replaceable class="parameter">table</replaceable>
29-
[ USING <replaceable class="parameter">acc_name</replaceable> ] ( <replaceable class="parameter">func_name</replaceable>( <replaceable class="parameter">column</replaceable> [, ... ]) [ <replaceable class="parameter">ops_name</replaceable> ] )
30+
[ USING <replaceable class="parameter">acc_method</replaceable> ] ( <replaceable class="parameter">func_name</replaceable>( <replaceable class="parameter">column</replaceable> [, ... ]) [ <replaceable class="parameter">ops_name</replaceable> ] )
31+
[ WHERE <replaceable class="parameter">predicate</replaceable> ]
3032
</synopsis>
3133

3234
<refsect2 id="R2-SQL-CREATEINDEX-1">
@@ -71,12 +73,12 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">index_name</replaceable>
7173
</varlistentry>
7274

7375
<varlistentry>
74-
<term><replaceable class="parameter">acc_name</replaceable></term>
76+
<term><replaceable class="parameter">acc_method</replaceable></term>
7577
<listitem>
7678
<para>
7779
The name of the access method to be used for
7880
the index. The default access method is BTREE.
79-
Postgres providesthree access methods for indexes:
81+
Postgres providesfour access methods for indexes:
8082

8183
<variablelist>
8284
<varlistentry>
@@ -106,6 +108,15 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">index_name</replaceable>
106108
</para>
107109
</listitem>
108110
</varlistentry>
111+
112+
<varlistentry>
113+
<term>GIST</term>
114+
<listitem>
115+
<para>
116+
Generalized Index Search Trees.
117+
</para>
118+
</listitem>
119+
</varlistentry>
109120
</variablelist>
110121
</para>
111122
</listitem>
@@ -137,6 +148,15 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">index_name</replaceable>
137148
</para>
138149
</listitem>
139150
</varlistentry>
151+
152+
<varlistentry>
153+
<term><replaceable class="parameter">predicate</replaceable></term>
154+
<listitem>
155+
<para>
156+
Defines the constraint expression for a partial index.
157+
</para>
158+
</listitem>
159+
</varlistentry>
140160
</variablelist>
141161
</para>
142162
</refsect2>
@@ -216,7 +236,7 @@ ERROR: Cannot create index: 'index_name' already exists.
216236
</para>
217237

218238
<para>
219-
Postgres provides btree, rtreeandhash access methods for
239+
Postgres provides btree, rtree, hash,andGiST access methods for
220240
indexes. The btree access method is an implementation of
221241
Lehman-Yao high-concurrency btrees. The rtree access method
222242
implements standard rtrees using Guttman's quadratic split algorithm.
@@ -227,6 +247,32 @@ ERROR: Cannot create index: 'index_name' already exists.
227247
access methods).
228248
</para>
229249

250+
<para>
251+
When the <command>WHERE</command> clause is present, a
252+
<firstterm>partial index</firstterm> is created.
253+
A partial index is an index that contains entries for only a portion of
254+
a table, usually a portion that is somehow more interesting than the
255+
rest of the table. For example, if you have a table that contains both
256+
billed and unbilled orders where the unbilled orders take up a small
257+
fraction of the total table and yet that is an often used section, you
258+
can improve performance by creating an index on just that portion.
259+
</para>
260+
261+
<para>
262+
The expression used in the <command>WHERE</command> clause may refer
263+
only to columns of the underlying table (but it can use all columns,
264+
not only the one(s) being indexed). Currently, the
265+
<productname>PostgreSQL</productname> planner can only devise query
266+
plans that make use of a partial index when the predicate is built from
267+
<command>AND</command> and <command>OR</command> combinations of
268+
elements of the form
269+
<firstterm>column</firstterm>
270+
<firstterm>operator</firstterm>
271+
<firstterm>constant</firstterm>.
272+
However, more general predicates may still be useful in conjunction
273+
with UNIQUE indexes, to enforce uniqueness over a subset of a table.
274+
</para>
275+
230276
<para>
231277
Use <xref linkend="sql-dropindex" endterm="sql-dropindex-title">
232278
to remove an index.
@@ -278,9 +324,10 @@ ERROR: Cannot create index: 'index_name' already exists.
278324
</para>
279325

280326
<para>
281-
Currently, only the btree accessmethod supports multi-column
327+
Currently, only the btreeand gistaccessmethods support multi-column
282328
indexes. Up to 16 keys may be specified by default (this limit
283-
can be altered when building Postgres).
329+
can be altered when building Postgres). Only btree currently supports
330+
unique indexes.
284331
</para>
285332

286333
<para>
@@ -307,9 +354,9 @@ ERROR: Cannot create index: 'index_name' already exists.
307354
The difference between them is that <literal>bigbox_ops</literal>
308355
scales box coordinates down, to avoid floating-point exceptions from
309356
doing multiplication, addition, and subtraction on very large
310-
floating-point coordinates.If the field on which your rectangles lie
311-
is about 20,000 units square or larger, you should use
312-
<literal>bigbox_ops</literal>.
357+
floating-point coordinates.(Note: this was true some time ago,
358+
but currently the two operator classes both use floating point
359+
and are effectively identical.)
313360
</para>
314361
</listitem>
315362
</itemizedlist>
@@ -319,15 +366,15 @@ ERROR: Cannot create index: 'index_name' already exists.
319366
The following query shows all defined operator classes:
320367

321368
<programlisting>
322-
SELECT am.amname ASacc_name,
369+
SELECT am.amname ASacc_method,
323370
opc.opcname AS ops_name,
324371
opr.oprname AS ops_comp
325372
FROM pg_am am, pg_amop amop,
326373
pg_opclass opc, pg_operator opr
327374
WHERE amop.amopid = am.oid AND
328375
amop.amopclaid = opc.oid AND
329376
amop.amopopr = opr.oid
330-
ORDER BYacc_name, ops_name, ops_comp
377+
ORDER BYacc_method, ops_name, ops_comp
331378
</programlisting>
332379
</para>
333380
</refsect2>

‎src/backend/bootstrap/bootstrap.c

Lines changed: 4 additions & 3 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-
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.111 2001/07/15 22:48:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.112 2001/07/16 05:06:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1100,8 +1100,9 @@ index_register(char *heap,
11001100
newind->il_info= (IndexInfo*)palloc(sizeof(IndexInfo));
11011101

11021102
memcpy(newind->il_info,indexInfo,sizeof(IndexInfo));
1103-
/* predicate will likely be null anyway, but may as well copy it */
1104-
newind->il_info->ii_Predicate=copyObject(indexInfo->ii_Predicate);
1103+
/* predicate will likely be null, but may as well copy it */
1104+
newind->il_info->ii_Predicate= (List*)
1105+
copyObject(indexInfo->ii_Predicate);
11051106

11061107
newind->il_next=ILHead;
11071108
ILHead=newind;

‎src/backend/catalog/index.c

Lines changed: 8 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.156 2001/07/15 22:48:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.157 2001/07/16 05:06:57 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -510,7 +510,7 @@ UpdateIndexRelation(Oid indexoid,
510510
* allocate a Form_pg_index big enough to hold the index-predicate (if
511511
* any) in string form
512512
*/
513-
if (indexInfo->ii_Predicate!=NULL)
513+
if (indexInfo->ii_Predicate!=NIL)
514514
{
515515
predString=nodeToString(indexInfo->ii_Predicate);
516516
predText=DatumGetTextP(DirectFunctionCall1(textin,
@@ -586,87 +586,6 @@ UpdateIndexRelation(Oid indexoid,
586586
heap_freetuple(tuple);
587587
}
588588

589-
/* ----------------------------------------------------------------
590-
*UpdateIndexPredicate
591-
* ----------------------------------------------------------------
592-
*/
593-
void
594-
UpdateIndexPredicate(Oidindexoid,Node*oldPred,Node*predicate)
595-
{
596-
Node*newPred;
597-
char*predString;
598-
text*predText;
599-
Relationpg_index;
600-
HeapTupletuple;
601-
HeapTuplenewtup;
602-
inti;
603-
Datumvalues[Natts_pg_index];
604-
charnulls[Natts_pg_index];
605-
charreplace[Natts_pg_index];
606-
607-
/*
608-
* Construct newPred as a CNF expression equivalent to the OR of the
609-
* original partial-index predicate ("oldPred") and the extension
610-
* predicate ("predicate").
611-
*
612-
* This should really try to process the result to change things like
613-
* "a>2 OR a>1" to simply "a>1", but for now all it does is make sure
614-
* that if the extension predicate is NULL (i.e., it is being extended
615-
* to be a complete index), then newPred will be NULL - in effect,
616-
* changing "a>2 OR TRUE" to "TRUE". --Nels, Jan '93
617-
*/
618-
newPred=NULL;
619-
if (predicate!=NULL)
620-
{
621-
newPred= (Node*)make_orclause(lcons(make_andclause((List*)predicate),
622-
lcons(make_andclause((List*)oldPred),
623-
NIL)));
624-
newPred= (Node*)cnfify((Expr*)newPred, true);
625-
}
626-
627-
/* translate the index-predicate to string form */
628-
if (newPred!=NULL)
629-
{
630-
predString=nodeToString(newPred);
631-
predText=DatumGetTextP(DirectFunctionCall1(textin,
632-
CStringGetDatum(predString)));
633-
pfree(predString);
634-
}
635-
else
636-
predText=DatumGetTextP(DirectFunctionCall1(textin,
637-
CStringGetDatum("")));
638-
639-
/* open the index system catalog relation */
640-
pg_index=heap_openr(IndexRelationName,RowExclusiveLock);
641-
642-
tuple=SearchSysCache(INDEXRELID,
643-
ObjectIdGetDatum(indexoid),
644-
0,0,0);
645-
if (!HeapTupleIsValid(tuple))
646-
elog(ERROR,"UpdateIndexPredicate: cache lookup failed for index %u",
647-
indexoid);
648-
649-
for (i=0;i<Natts_pg_index;i++)
650-
{
651-
nulls[i]=heap_attisnull(tuple,i+1) ?'n' :' ';
652-
replace[i]=' ';
653-
values[i]= (Datum)NULL;
654-
}
655-
656-
replace[Anum_pg_index_indpred-1]='r';
657-
values[Anum_pg_index_indpred-1]=PointerGetDatum(predText);
658-
659-
newtup=heap_modifytuple(tuple,pg_index,values,nulls,replace);
660-
661-
simple_heap_update(pg_index,&newtup->t_self,newtup);
662-
663-
heap_freetuple(newtup);
664-
ReleaseSysCache(tuple);
665-
666-
heap_close(pg_index,RowExclusiveLock);
667-
pfree(predText);
668-
}
669-
670589
/* ----------------------------------------------------------------
671590
*InitIndexStrategy
672591
*
@@ -1084,7 +1003,7 @@ BuildIndexInfo(HeapTuple indexTuple)
10841003
pfree(predString);
10851004
}
10861005
else
1087-
ii->ii_Predicate=NULL;
1006+
ii->ii_Predicate=NIL;
10881007

10891008
/* Other info */
10901009
ii->ii_Unique=indexStruct->indisunique;
@@ -1684,7 +1603,7 @@ IndexBuildHeapScan(Relation heapRelation,
16841603
Datumattdata[INDEX_MAX_KEYS];
16851604
charnulls[INDEX_MAX_KEYS];
16861605
doublereltuples;
1687-
Node*predicate=indexInfo->ii_Predicate;
1606+
List*predicate=indexInfo->ii_Predicate;
16881607
TupleTabletupleTable;
16891608
TupleTableSlot*slot;
16901609
ExprContext*econtext;
@@ -1708,7 +1627,7 @@ IndexBuildHeapScan(Relation heapRelation,
17081627
* We construct the ExprContext anyway since we need a per-tuple
17091628
* temporary memory context for function evaluation -- tgl July 00
17101629
*/
1711-
if (predicate!=NULL)
1630+
if (predicate!=NIL)
17121631
{
17131632
tupleTable=ExecCreateTupleTable(1);
17141633
slot=ExecAllocTableSlot(tupleTable);
@@ -1831,12 +1750,12 @@ IndexBuildHeapScan(Relation heapRelation,
18311750
* VACUUM doesn't complain about tuple count mismatch for partial
18321751
* indexes.
18331752
*/
1834-
if (predicate!=NULL)
1753+
if (predicate!=NIL)
18351754
{
18361755
if (!tupleIsAlive)
18371756
continue;
18381757
ExecStoreTuple(heapTuple,slot,InvalidBuffer, false);
1839-
if (!ExecQual((List*)predicate,econtext, false))
1758+
if (!ExecQual(predicate,econtext, false))
18401759
continue;
18411760
}
18421761

@@ -1865,7 +1784,7 @@ IndexBuildHeapScan(Relation heapRelation,
18651784

18661785
heap_endscan(scan);
18671786

1868-
if (predicate!=NULL)
1787+
if (predicate!=NIL)
18691788
ExecDropTupleTable(tupleTable, true);
18701789
FreeExprContext(econtext);
18711790

‎src/backend/commands/command.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.135 2001/07/15 22:48:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.136 2001/07/16 05:06:57 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -1882,7 +1882,7 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
18821882
indexInfo->ii_NumIndexAttrs=1;
18831883
indexInfo->ii_NumKeyAttrs=1;
18841884
indexInfo->ii_KeyAttrNumbers[0]=1;
1885-
indexInfo->ii_Predicate=NULL;
1885+
indexInfo->ii_Predicate=NIL;
18861886
indexInfo->ii_FuncOid=InvalidOid;
18871887
indexInfo->ii_Unique= false;
18881888

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp