Cross-data-type comparisons are now indexable by btrees, pursuant to my
pghackers proposal of 8-Nov. All the existing cross-type comparison operators (int2/int4/int8 and float4/float8) have appropriate support. The original proposal of storing the right-hand-side datatype as part of the primary key for pg_amop and pg_amproc got modified a bit in the event; it is easier to store zero as the 'default' case and only store a nonzero when the operator is actually cross-type. Along the way, remove the long-since-defunct bigbox_ops operator class.
This commit is contained in:
parent
49f98fa833
commit
fa5c8a055a
|
@ -1357,10 +1357,10 @@ get_pkey_attnames(Oid relid, int16 *numatts)
|
||||||
|
|
||||||
/* use relid to get all related indexes */
|
/* use relid to get all related indexes */
|
||||||
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
|
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry, 0,
|
ScanKeyInit(&entry,
|
||||||
Anum_pg_index_indrelid,
|
Anum_pg_index_indrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
|
scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
|
||||||
|
|
||||||
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "access/tupdesc.h"
|
#include "access/tupdesc.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/pg_listener.h"
|
#include "catalog/pg_listener.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
|
@ -87,10 +86,10 @@ active_listeners(text *relname)
|
||||||
MemSet(listen_name, 0, NAMEDATALEN);
|
MemSet(listen_name, 0, NAMEDATALEN);
|
||||||
len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
|
len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
|
||||||
memcpy(listen_name, VARDATA(relname), len);
|
memcpy(listen_name, VARDATA(relname), len);
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_listener_relname,
|
Anum_pg_listener_relname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(listen_name), NAMEOID);
|
PointerGetDatum(listen_name));
|
||||||
sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
|
sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.78 2003/11/02 12:53:57 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.79 2003/11/12 21:15:42 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="catalogs">
|
<chapter id="catalogs">
|
||||||
|
@ -499,6 +499,14 @@
|
||||||
<entry>The index operator class this entry is for</entry>
|
<entry>The index operator class this entry is for</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structfield>amopsubtype</structfield></entry>
|
||||||
|
<entry><type>oid</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
||||||
|
<entry>Subtype to distinguish multiple entries for one strategy;
|
||||||
|
zero for default</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>amopstrategy</structfield></entry>
|
<entry><structfield>amopstrategy</structfield></entry>
|
||||||
<entry><type>int2</type></entry>
|
<entry><type>int2</type></entry>
|
||||||
|
@ -562,6 +570,13 @@
|
||||||
<entry>The index operator class this entry is for</entry>
|
<entry>The index operator class this entry is for</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structfield>amprocsubtype</structfield></entry>
|
||||||
|
<entry><type>oid</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
||||||
|
<entry>Subtype, if cross-type routine, else zero</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>amprocnum</structfield></entry>
|
<entry><structfield>amprocnum</structfield></entry>
|
||||||
<entry><type>int2</type></entry>
|
<entry><type>int2</type></entry>
|
||||||
|
@ -2435,7 +2450,7 @@
|
||||||
<entry><structfield>opcintype</structfield></entry>
|
<entry><structfield>opcintype</structfield></entry>
|
||||||
<entry><type>oid</type></entry>
|
<entry><type>oid</type></entry>
|
||||||
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
||||||
<entry>Input data type of the operator class</entry>
|
<entry>Data type that the operator class indexes</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
|
@ -2449,7 +2464,7 @@
|
||||||
<entry><structfield>opckeytype</structfield></entry>
|
<entry><structfield>opckeytype</structfield></entry>
|
||||||
<entry><type>oid</type></entry>
|
<entry><type>oid</type></entry>
|
||||||
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
|
||||||
<entry>Type of index data, or zero if same as <structfield>opcintype</></entry>
|
<entry>Type of data stored in index, or zero if same as <structfield>opcintype</></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.34 2003/11/01 01:56:29 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.35 2003/11/12 21:15:45 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<sect1 id="xindex">
|
<sect1 id="xindex">
|
||||||
|
@ -80,7 +80,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.34 2003/11/01 01:56:29 pete
|
||||||
The same operator class name
|
The same operator class name
|
||||||
can be used for several different index methods (for example, both B-tree
|
can be used for several different index methods (for example, both B-tree
|
||||||
and hash index methods have operator classes named
|
and hash index methods have operator classes named
|
||||||
<literal>oid_ops</literal>), but each such class is an independent
|
<literal>int4_ops</literal>), but each such class is an independent
|
||||||
entity and must be defined separately.
|
entity and must be defined separately.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
@ -589,6 +589,71 @@ CREATE OPERATOR CLASS complex_abs_ops
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="xindex-opclass-crosstype">
|
||||||
|
<title>Cross-Data-Type Operator Classes</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
So far we have implicitly assumed that an operator class deals with
|
||||||
|
only one data type. While there certainly can be only one data type in
|
||||||
|
a particular index column, it is often useful to index operations that
|
||||||
|
compare an indexed column to a value of a different data type. This is
|
||||||
|
presently supported by the B-tree and GiST index methods.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
B-trees require the left-hand operand of each operator to be the indexed
|
||||||
|
data type, but the right-hand operand can be of a different type. There
|
||||||
|
must be a support function having a matching signature. For example,
|
||||||
|
the built-in operator class for type <type>bigint</> (<type>int8</>)
|
||||||
|
allows cross-type comparisons to <type>int4</> and <type>int2</>. It
|
||||||
|
could be duplicated by this definition:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
CREATE OPERATOR CLASS int8_ops
|
||||||
|
DEFAULT FOR TYPE int8 USING btree AS
|
||||||
|
-- standard int8 comparisons
|
||||||
|
OPERATOR 1 < ,
|
||||||
|
OPERATOR 2 <= ,
|
||||||
|
OPERATOR 3 = ,
|
||||||
|
OPERATOR 4 >= ,
|
||||||
|
OPERATOR 5 > ,
|
||||||
|
FUNCTION 1 btint8cmp(int8, int8) ,
|
||||||
|
|
||||||
|
-- cross-type comparisons to int2 (smallint)
|
||||||
|
OPERATOR 1 < (int8, int2) ,
|
||||||
|
OPERATOR 2 <= (int8, int2) ,
|
||||||
|
OPERATOR 3 = (int8, int2) ,
|
||||||
|
OPERATOR 4 >= (int8, int2) ,
|
||||||
|
OPERATOR 5 > (int8, int2) ,
|
||||||
|
FUNCTION 1 btint82cmp(int8, int2) ,
|
||||||
|
|
||||||
|
-- cross-type comparisons to int4 (integer)
|
||||||
|
OPERATOR 1 < (int8, int4) ,
|
||||||
|
OPERATOR 2 <= (int8, int4) ,
|
||||||
|
OPERATOR 3 = (int8, int4) ,
|
||||||
|
OPERATOR 4 >= (int8, int4) ,
|
||||||
|
OPERATOR 5 > (int8, int4) ,
|
||||||
|
FUNCTION 1 btint84cmp(int8, int4) ;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Notice that this definition <quote>overloads</> the operator strategy and
|
||||||
|
support function numbers. This is allowed (for B-tree operator classes
|
||||||
|
only) so long as each instance of a particular number has a different
|
||||||
|
right-hand data type. The instances that are not cross-type are the
|
||||||
|
default or primary operators of the operator class.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
GiST indexes do not allow overloading of strategy or support function
|
||||||
|
numbers, but it is still possible to get the effect of supporting
|
||||||
|
multiple right-hand data types, by assigning a distinct strategy number
|
||||||
|
to each operator that needs to be supported. The <literal>consistent</>
|
||||||
|
support function must determine what it needs to do based on the strategy
|
||||||
|
number, and must be prepared to accept comparison values of the appropriate
|
||||||
|
data types.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="xindex-opclass-dependencies">
|
<sect2 id="xindex-opclass-dependencies">
|
||||||
<title>System Dependencies on Operator Classes</title>
|
<title>System Dependencies on Operator Classes</title>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.23 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.24 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -31,15 +31,43 @@ ScanKeyEntryInitialize(ScanKey entry,
|
||||||
int flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
StrategyNumber strategy,
|
StrategyNumber strategy,
|
||||||
|
Oid subtype,
|
||||||
RegProcedure procedure,
|
RegProcedure procedure,
|
||||||
Datum argument,
|
Datum argument)
|
||||||
Oid argtype)
|
|
||||||
{
|
{
|
||||||
entry->sk_flags = flags;
|
entry->sk_flags = flags;
|
||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_strategy = strategy;
|
entry->sk_strategy = strategy;
|
||||||
|
entry->sk_subtype = subtype;
|
||||||
|
entry->sk_argument = argument;
|
||||||
|
fmgr_info(procedure, &entry->sk_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ScanKeyInit
|
||||||
|
* Shorthand version of ScanKeyEntryInitialize: flags and subtype
|
||||||
|
* are assumed to be zero (the usual value).
|
||||||
|
*
|
||||||
|
* This is the recommended version for hardwired lookups in system catalogs.
|
||||||
|
* It cannot handle NULL arguments, unary operators, or nondefault operators,
|
||||||
|
* but we need none of those features for most hardwired lookups.
|
||||||
|
*
|
||||||
|
* Note: CurrentMemoryContext at call should be as long-lived as the ScanKey
|
||||||
|
* itself, because that's what will be used for any subsidiary info attached
|
||||||
|
* to the ScanKey's FmgrInfo record.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ScanKeyInit(ScanKey entry,
|
||||||
|
AttrNumber attributeNumber,
|
||||||
|
StrategyNumber strategy,
|
||||||
|
RegProcedure procedure,
|
||||||
|
Datum argument)
|
||||||
|
{
|
||||||
|
entry->sk_flags = 0;
|
||||||
|
entry->sk_attno = attributeNumber;
|
||||||
|
entry->sk_strategy = strategy;
|
||||||
|
entry->sk_subtype = InvalidOid;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
entry->sk_argtype = argtype;
|
|
||||||
fmgr_info(procedure, &entry->sk_func);
|
fmgr_info(procedure, &entry->sk_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +85,14 @@ ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
||||||
int flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
StrategyNumber strategy,
|
StrategyNumber strategy,
|
||||||
|
Oid subtype,
|
||||||
FmgrInfo *finfo,
|
FmgrInfo *finfo,
|
||||||
Datum argument,
|
Datum argument)
|
||||||
Oid argtype)
|
|
||||||
{
|
{
|
||||||
entry->sk_flags = flags;
|
entry->sk_flags = flags;
|
||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_strategy = strategy;
|
entry->sk_strategy = strategy;
|
||||||
|
entry->sk_subtype = subtype;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
entry->sk_argtype = argtype;
|
|
||||||
fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
|
fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.37 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.38 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -221,40 +221,50 @@ gistindex_keytest(IndexTuple tuple,
|
||||||
Page p,
|
Page p,
|
||||||
OffsetNumber offset)
|
OffsetNumber offset)
|
||||||
{
|
{
|
||||||
bool isNull;
|
|
||||||
Datum datum;
|
|
||||||
Datum test;
|
|
||||||
GISTENTRY de;
|
|
||||||
|
|
||||||
IncrIndexProcessed();
|
IncrIndexProcessed();
|
||||||
|
|
||||||
while (scanKeySize > 0)
|
while (scanKeySize > 0)
|
||||||
{
|
{
|
||||||
|
Datum datum;
|
||||||
|
bool isNull;
|
||||||
|
Datum test;
|
||||||
|
GISTENTRY de;
|
||||||
|
|
||||||
datum = index_getattr(tuple,
|
datum = index_getattr(tuple,
|
||||||
key[0].sk_attno,
|
key->sk_attno,
|
||||||
giststate->tupdesc,
|
giststate->tupdesc,
|
||||||
&isNull);
|
&isNull);
|
||||||
|
/* is the index entry NULL? */
|
||||||
if (isNull)
|
if (isNull)
|
||||||
{
|
{
|
||||||
/* XXX eventually should check if SK_ISNULL */
|
/* XXX eventually should check if SK_ISNULL */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/* is the compared-to datum NULL? */
|
||||||
/* this code from backend/access/common/indexvalid.c. But why and what???
|
if (key->sk_flags & SK_ISNULL)
|
||||||
if (key[0].sk_flags & SK_ISNULL)
|
|
||||||
return false;
|
return false;
|
||||||
*/
|
|
||||||
gistdentryinit(giststate, key[0].sk_attno - 1, &de,
|
gistdentryinit(giststate, key->sk_attno - 1, &de,
|
||||||
datum, r, p, offset,
|
datum, r, p, offset,
|
||||||
IndexTupleSize(tuple) - sizeof(IndexTupleData),
|
IndexTupleSize(tuple) - sizeof(IndexTupleData),
|
||||||
FALSE, isNull);
|
FALSE, isNull);
|
||||||
|
|
||||||
test = FunctionCall3(&key[0].sk_func,
|
/*
|
||||||
|
* Call the Consistent function to evaluate the test. The arguments
|
||||||
|
* are the index datum (as a GISTENTRY*), the comparison datum, and
|
||||||
|
* the comparison operator's strategy number and subtype from pg_amop.
|
||||||
|
*
|
||||||
|
* (Presently there's no need to pass the subtype since it'll always
|
||||||
|
* be zero, but might as well pass it for possible future use.)
|
||||||
|
*/
|
||||||
|
test = FunctionCall4(&key->sk_func,
|
||||||
PointerGetDatum(&de),
|
PointerGetDatum(&de),
|
||||||
key[0].sk_argument,
|
key->sk_argument,
|
||||||
Int32GetDatum(key[0].sk_strategy));
|
Int32GetDatum(key->sk_strategy),
|
||||||
|
ObjectIdGetDatum(key->sk_subtype));
|
||||||
|
|
||||||
if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1))
|
/* if index datum had to be decompressed, free it */
|
||||||
|
if (de.key != datum && !isAttByVal(giststate, key->sk_attno - 1))
|
||||||
if (DatumGetPointer(de.key) != NULL)
|
if (DatumGetPointer(de.key) != NULL)
|
||||||
pfree(DatumGetPointer(de.key));
|
pfree(DatumGetPointer(de.key));
|
||||||
|
|
||||||
|
@ -264,6 +274,7 @@ gistindex_keytest(IndexTuple tuple,
|
||||||
scanKeySize--;
|
scanKeySize--;
|
||||||
key++;
|
key++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.49 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -109,7 +109,8 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||||
* Modify the scan key so that the Consistent function is called
|
* Modify the scan key so that the Consistent function is called
|
||||||
* for all comparisons. The original operator is passed to the
|
* for all comparisons. The original operator is passed to the
|
||||||
* Consistent function in the form of its strategy number, which
|
* Consistent function in the form of its strategy number, which
|
||||||
* is available from the sk_strategy field.
|
* is available from the sk_strategy field, and its subtype from
|
||||||
|
* the sk_subtype field.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < s->numberOfKeys; i++)
|
for (i = 0; i < s->numberOfKeys; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.39 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.40 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/tuptoaster.h"
|
#include "access/tuptoaster.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
@ -968,11 +967,10 @@ toast_delete_datum(Relation rel, Datum value)
|
||||||
* Setup a scan key to fetch from the index by va_valueid (we don't
|
* Setup a scan key to fetch from the index by va_valueid (we don't
|
||||||
* particularly care whether we see them in sequence or not)
|
* particularly care whether we see them in sequence or not)
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&toastkey, 0,
|
ScanKeyInit(&toastkey,
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
|
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the chunks by index
|
* Find the chunks by index
|
||||||
|
@ -1040,11 +1038,10 @@ toast_fetch_datum(varattrib *attr)
|
||||||
/*
|
/*
|
||||||
* Setup a scan key to fetch from the index by va_valueid
|
* Setup a scan key to fetch from the index by va_valueid
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&toastkey, 0,
|
ScanKeyInit(&toastkey,
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
|
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the chunks by index
|
* Read the chunks by index
|
||||||
|
@ -1195,33 +1192,32 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
|
||||||
* Setup a scan key to fetch from the index. This is either two keys
|
* Setup a scan key to fetch from the index. This is either two keys
|
||||||
* or three depending on the number of chunks.
|
* or three depending on the number of chunks.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&toastkey[0], 0,
|
ScanKeyInit(&toastkey[0],
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
|
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use equality condition for one chunk, a range condition otherwise:
|
* Use equality condition for one chunk, a range condition otherwise:
|
||||||
*/
|
*/
|
||||||
if (numchunks == 1)
|
if (numchunks == 1)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&toastkey[1], 0,
|
ScanKeyInit(&toastkey[1],
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(startchunk), INT4OID);
|
Int32GetDatum(startchunk));
|
||||||
nscankeys = 2;
|
nscankeys = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&toastkey[1], 0,
|
ScanKeyInit(&toastkey[1],
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
Int32GetDatum(startchunk), INT4OID);
|
Int32GetDatum(startchunk));
|
||||||
ScanKeyEntryInitialize(&toastkey[2], 0,
|
ScanKeyInit(&toastkey[2],
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
BTLessEqualStrategyNumber, F_INT4LE,
|
BTLessEqualStrategyNumber, F_INT4LE,
|
||||||
Int32GetDatum(endchunk), INT4OID);
|
Int32GetDatum(endchunk));
|
||||||
nscankeys = 3;
|
nscankeys = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.46 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.47 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
|
@ -97,6 +97,90 @@ btint8cmp(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_INT32(-1);
|
PG_RETURN_INT32(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint48cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int32 a = PG_GETARG_INT32(0);
|
||||||
|
int64 b = PG_GETARG_INT64(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint84cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int64 a = PG_GETARG_INT64(0);
|
||||||
|
int32 b = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint24cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int16 a = PG_GETARG_INT16(0);
|
||||||
|
int32 b = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint42cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int32 a = PG_GETARG_INT32(0);
|
||||||
|
int16 b = PG_GETARG_INT16(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint28cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int16 a = PG_GETARG_INT16(0);
|
||||||
|
int64 b = PG_GETARG_INT64(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btint82cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int64 a = PG_GETARG_INT64(0);
|
||||||
|
int16 b = PG_GETARG_INT16(1);
|
||||||
|
|
||||||
|
if (a > b)
|
||||||
|
PG_RETURN_INT32(1);
|
||||||
|
else if (a == b)
|
||||||
|
PG_RETURN_INT32(0);
|
||||||
|
else
|
||||||
|
PG_RETURN_INT32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
btoidcmp(PG_FUNCTION_ARGS)
|
btoidcmp(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.107 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.108 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1577,26 +1577,27 @@ _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
|
||||||
|
|
||||||
for (i = 1; i <= keysz; i++)
|
for (i = 1; i <= keysz; i++)
|
||||||
{
|
{
|
||||||
ScanKey entry = &scankey[i - 1];
|
|
||||||
AttrNumber attno;
|
AttrNumber attno;
|
||||||
Datum datum;
|
Datum datum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
int32 result;
|
int32 result;
|
||||||
|
|
||||||
attno = entry->sk_attno;
|
attno = scankey->sk_attno;
|
||||||
Assert(attno == i);
|
Assert(attno == i);
|
||||||
datum = index_getattr(itup, attno, itupdesc, &isNull);
|
datum = index_getattr(itup, attno, itupdesc, &isNull);
|
||||||
|
|
||||||
/* NULLs are never equal to anything */
|
/* NULLs are never equal to anything */
|
||||||
if ((entry->sk_flags & SK_ISNULL) || isNull)
|
if (isNull || (scankey->sk_flags & SK_ISNULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
result = DatumGetInt32(FunctionCall2(&entry->sk_func,
|
result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
|
||||||
entry->sk_argument,
|
datum,
|
||||||
datum));
|
scankey->sk_argument));
|
||||||
|
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
scankey++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we get here, the keys are equal */
|
/* if we get here, the keys are equal */
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.106 2003/09/29 23:40:26 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.107 2003/11/12 21:15:46 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -397,7 +397,6 @@ btrescan(PG_FUNCTION_ARGS)
|
||||||
so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
|
so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
|
||||||
else
|
else
|
||||||
so->keyData = (ScanKey) NULL;
|
so->keyData = (ScanKey) NULL;
|
||||||
so->numberOfKeys = scan->numberOfKeys;
|
|
||||||
scan->opaque = so;
|
scan->opaque = so;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,38 +422,14 @@ btrescan(PG_FUNCTION_ARGS)
|
||||||
* _bt_first. - vadim 05/05/97
|
* _bt_first. - vadim 05/05/97
|
||||||
*/
|
*/
|
||||||
if (scankey && scan->numberOfKeys > 0)
|
if (scankey && scan->numberOfKeys > 0)
|
||||||
{
|
|
||||||
memmove(scan->keyData,
|
memmove(scan->keyData,
|
||||||
scankey,
|
scankey,
|
||||||
scan->numberOfKeys * sizeof(ScanKeyData));
|
scan->numberOfKeys * sizeof(ScanKeyData));
|
||||||
so->numberOfKeys = scan->numberOfKeys;
|
so->numberOfKeys = 0; /* until _bt_preprocess_keys sets it */
|
||||||
memmove(so->keyData,
|
|
||||||
scankey,
|
|
||||||
so->numberOfKeys * sizeof(ScanKeyData));
|
|
||||||
}
|
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
btmovescan(IndexScanDesc scan, Datum v)
|
|
||||||
{
|
|
||||||
ItemPointer iptr;
|
|
||||||
BTScanOpaque so;
|
|
||||||
|
|
||||||
so = (BTScanOpaque) scan->opaque;
|
|
||||||
|
|
||||||
/* we aren't holding any read locks, but gotta drop the pin */
|
|
||||||
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
|
|
||||||
{
|
|
||||||
ReleaseBuffer(so->btso_curbuf);
|
|
||||||
so->btso_curbuf = InvalidBuffer;
|
|
||||||
ItemPointerSetInvalid(iptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
so->keyData[0].sk_argument = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btendscan() -- close down a scan
|
* btendscan() -- close down a scan
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.81 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.82 2003/11/12 21:15:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
static Buffer _bt_walk_left(Relation rel, Buffer buf);
|
static Buffer _bt_walk_left(Relation rel, Buffer buf);
|
||||||
|
@ -325,17 +326,16 @@ _bt_compare(Relation rel,
|
||||||
* (see _bt_first).
|
* (see _bt_first).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < keysz; i++)
|
for (i = 1; i <= keysz; i++)
|
||||||
{
|
{
|
||||||
ScanKey entry = &scankey[i];
|
|
||||||
Datum datum;
|
Datum datum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
int32 result;
|
int32 result;
|
||||||
|
|
||||||
datum = index_getattr(itup, entry->sk_attno, itupdesc, &isNull);
|
datum = index_getattr(itup, scankey->sk_attno, itupdesc, &isNull);
|
||||||
|
|
||||||
/* see comments about NULLs handling in btbuild */
|
/* see comments about NULLs handling in btbuild */
|
||||||
if (entry->sk_flags & SK_ISNULL) /* key is NULL */
|
if (scankey->sk_flags & SK_ISNULL) /* key is NULL */
|
||||||
{
|
{
|
||||||
if (isNull)
|
if (isNull)
|
||||||
result = 0; /* NULL "=" NULL */
|
result = 0; /* NULL "=" NULL */
|
||||||
|
@ -348,14 +348,28 @@ _bt_compare(Relation rel,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = DatumGetInt32(FunctionCall2(&entry->sk_func,
|
/*
|
||||||
entry->sk_argument,
|
* The sk_func needs to be passed the index value as left arg
|
||||||
datum));
|
* and the sk_argument as right arg (they might be of different
|
||||||
|
* types). Since it is convenient for callers to think of
|
||||||
|
* _bt_compare as comparing the scankey to the index item,
|
||||||
|
* we have to flip the sign of the comparison result.
|
||||||
|
*
|
||||||
|
* Note: curious-looking coding is to avoid overflow if
|
||||||
|
* comparison function returns INT_MIN. There is no risk of
|
||||||
|
* overflow for positive results.
|
||||||
|
*/
|
||||||
|
result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
|
||||||
|
datum,
|
||||||
|
scankey->sk_argument));
|
||||||
|
result = (result < 0) ? 1 : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the keys are unequal, return the difference */
|
/* if the keys are unequal, return the difference */
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
scankey++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we get here, the keys are equal */
|
/* if we get here, the keys are equal */
|
||||||
|
@ -448,126 +462,203 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||||
StrategyNumber strat;
|
StrategyNumber strat;
|
||||||
bool res;
|
bool res;
|
||||||
int32 result;
|
int32 result;
|
||||||
bool scanFromEnd;
|
|
||||||
bool continuescan;
|
bool continuescan;
|
||||||
ScanKey scankeys = NULL;
|
ScanKey scankeys = NULL;
|
||||||
|
ScanKey *startKeys = NULL;
|
||||||
int keysCount = 0;
|
int keysCount = 0;
|
||||||
int *nKeyIs = NULL;
|
int i;
|
||||||
int i,
|
|
||||||
j;
|
|
||||||
StrategyNumber strat_total;
|
StrategyNumber strat_total;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Order the scan keys in our canonical fashion and eliminate any
|
* Examine the scan keys and eliminate any redundant keys; also
|
||||||
* redundant keys.
|
* discover how many keys must be matched to continue the scan.
|
||||||
*/
|
*/
|
||||||
_bt_orderkeys(scan);
|
_bt_preprocess_keys(scan);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Quit now if _bt_orderkeys() discovered that the scan keys can never
|
* Quit now if _bt_preprocess_keys() discovered that the scan keys can
|
||||||
* be satisfied (eg, x == 1 AND x > 2).
|
* never be satisfied (eg, x == 1 AND x > 2).
|
||||||
*/
|
*/
|
||||||
if (!so->qual_ok)
|
if (!so->qual_ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*----------
|
||||||
* Examine the scan keys to discover where we need to start the scan.
|
* Examine the scan keys to discover where we need to start the scan.
|
||||||
|
*
|
||||||
|
* We want to identify the keys that can be used as starting boundaries;
|
||||||
|
* these are =, >, or >= keys for a forward scan or =, <, <= keys for
|
||||||
|
* a backwards scan. We can use keys for multiple attributes so long as
|
||||||
|
* the prior attributes had only =, >= (resp. =, <=) keys. Once we accept
|
||||||
|
* a > or < boundary or find an attribute with no boundary (which can be
|
||||||
|
* thought of as the same as "> -infinity"), we can't use keys for any
|
||||||
|
* attributes to its right, because it would break our simplistic notion
|
||||||
|
* of what initial positioning strategy to use.
|
||||||
|
*
|
||||||
|
* When the scan keys include non-default operators, _bt_preprocess_keys
|
||||||
|
* may not be able to eliminate redundant keys; in such cases we will
|
||||||
|
* arbitrarily pick a usable one for each attribute. This is correct
|
||||||
|
* but possibly not optimal behavior. (For example, with keys like
|
||||||
|
* "x >= 4 AND x >= 5" we would elect to scan starting at x=4 when
|
||||||
|
* x=5 would be more efficient.) Since the situation only arises in
|
||||||
|
* hokily-worded queries, live with it.
|
||||||
|
*
|
||||||
|
* When both equality and inequality keys appear for a single attribute
|
||||||
|
* (again, only possible when non-default operators appear), we *must*
|
||||||
|
* select one of the equality keys for the starting point, because
|
||||||
|
* _bt_checkkeys() will stop the scan as soon as an equality qual fails.
|
||||||
|
* For example, if we have keys like "x >= 4 AND x = 10" and we elect to
|
||||||
|
* start at x=4, we will fail and stop before reaching x=10. If multiple
|
||||||
|
* equality quals survive preprocessing, however, it doesn't matter which
|
||||||
|
* one we use --- by definition, they are either redundant or
|
||||||
|
* contradictory.
|
||||||
|
*----------
|
||||||
*/
|
*/
|
||||||
scanFromEnd = false;
|
|
||||||
strat_total = BTEqualStrategyNumber;
|
strat_total = BTEqualStrategyNumber;
|
||||||
if (so->numberOfKeys > 0)
|
if (so->numberOfKeys > 0)
|
||||||
{
|
{
|
||||||
nKeyIs = (int *) palloc(so->numberOfKeys * sizeof(int));
|
AttrNumber curattr;
|
||||||
for (i = 0; i < so->numberOfKeys; i++)
|
ScanKey chosen;
|
||||||
{
|
ScanKey cur;
|
||||||
AttrNumber attno = so->keyData[i].sk_attno;
|
|
||||||
|
|
||||||
/* ignore keys for already-determined attrs */
|
startKeys = (ScanKey *) palloc(so->numberOfKeys * sizeof(ScanKey));
|
||||||
if (attno <= keysCount)
|
/*
|
||||||
continue;
|
* chosen is the so-far-chosen key for the current attribute, if any.
|
||||||
/* if we didn't find a boundary for the preceding attr, quit */
|
* We don't cast the decision in stone until we reach keys for the
|
||||||
if (attno > keysCount + 1)
|
* next attribute.
|
||||||
|
*/
|
||||||
|
curattr = 1;
|
||||||
|
chosen = NULL;
|
||||||
|
/*
|
||||||
|
* Loop iterates from 0 to numberOfKeys inclusive; we use the last
|
||||||
|
* pass to handle after-last-key processing. Actual exit from the
|
||||||
|
* loop is at one of the "break" statements below.
|
||||||
|
*/
|
||||||
|
for (cur = so->keyData, i = 0;; cur++, i++)
|
||||||
|
{
|
||||||
|
if (i >= so->numberOfKeys || cur->sk_attno != curattr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Done looking at keys for curattr. If we didn't find a
|
||||||
|
* usable boundary key, quit; else save the boundary key
|
||||||
|
* pointer in startKeys.
|
||||||
|
*/
|
||||||
|
if (chosen == NULL)
|
||||||
break;
|
break;
|
||||||
|
startKeys[keysCount++] = chosen;
|
||||||
|
/*
|
||||||
|
* Adjust strat_total, and quit if we have stored a > or < key.
|
||||||
|
*/
|
||||||
|
strat = chosen->sk_strategy;
|
||||||
|
if (strat != BTEqualStrategyNumber)
|
||||||
|
{
|
||||||
|
strat_total = strat;
|
||||||
|
if (strat == BTGreaterStrategyNumber ||
|
||||||
|
strat == BTLessStrategyNumber)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Done if that was the last attribute.
|
||||||
|
*/
|
||||||
|
if (i >= so->numberOfKeys)
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* Reset for next attr, which should be in sequence.
|
||||||
|
*/
|
||||||
|
Assert(cur->sk_attno == curattr + 1);
|
||||||
|
curattr = cur->sk_attno;
|
||||||
|
chosen = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can we use this key as a starting boundary for this attr? */
|
||||||
|
switch (cur->sk_strategy)
|
||||||
|
{
|
||||||
|
case BTLessStrategyNumber:
|
||||||
|
case BTLessEqualStrategyNumber:
|
||||||
|
if (chosen == NULL && ScanDirectionIsBackward(dir))
|
||||||
|
chosen = cur;
|
||||||
|
break;
|
||||||
|
case BTEqualStrategyNumber:
|
||||||
|
/* override any non-equality choice */
|
||||||
|
chosen = cur;
|
||||||
|
break;
|
||||||
|
case BTGreaterEqualStrategyNumber:
|
||||||
|
case BTGreaterStrategyNumber:
|
||||||
|
if (chosen == NULL && ScanDirectionIsForward(dir))
|
||||||
|
chosen = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can we use this key as a starting boundary for this attr?
|
* If we found no usable boundary keys, we have to start from one end
|
||||||
*
|
* of the tree. Walk down that edge to the first or last key, and
|
||||||
* We can use multiple keys if they look like, say, = >= = but we
|
* scan from there.
|
||||||
* have to stop after accepting a > or < boundary.
|
|
||||||
*/
|
*/
|
||||||
strat = so->keyData[i].sk_strategy;
|
|
||||||
if (strat == strat_total ||
|
|
||||||
strat == BTEqualStrategyNumber)
|
|
||||||
nKeyIs[keysCount++] = i;
|
|
||||||
else if (ScanDirectionIsBackward(dir) &&
|
|
||||||
(strat == BTLessStrategyNumber ||
|
|
||||||
strat == BTLessEqualStrategyNumber))
|
|
||||||
{
|
|
||||||
nKeyIs[keysCount++] = i;
|
|
||||||
strat_total = strat;
|
|
||||||
if (strat == BTLessStrategyNumber)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (ScanDirectionIsForward(dir) &&
|
|
||||||
(strat == BTGreaterStrategyNumber ||
|
|
||||||
strat == BTGreaterEqualStrategyNumber))
|
|
||||||
{
|
|
||||||
nKeyIs[keysCount++] = i;
|
|
||||||
strat_total = strat;
|
|
||||||
if (strat == BTGreaterStrategyNumber)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (keysCount == 0)
|
if (keysCount == 0)
|
||||||
scanFromEnd = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
scanFromEnd = true;
|
|
||||||
|
|
||||||
/* if we just need to walk down one edge of the tree, do that */
|
|
||||||
if (scanFromEnd)
|
|
||||||
{
|
{
|
||||||
if (nKeyIs)
|
if (startKeys)
|
||||||
pfree(nKeyIs);
|
pfree(startKeys);
|
||||||
return _bt_endpoint(scan, dir);
|
return _bt_endpoint(scan, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to start the scan somewhere within the index. Set up a
|
* We want to start the scan somewhere within the index. Set up a
|
||||||
* scankey we can use to search for the correct starting point.
|
* 3-way-comparison scankey we can use to search for the boundary
|
||||||
|
* point we identified above.
|
||||||
*/
|
*/
|
||||||
scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
|
scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
|
||||||
for (i = 0; i < keysCount; i++)
|
for (i = 0; i < keysCount; i++)
|
||||||
{
|
{
|
||||||
FmgrInfo *procinfo;
|
ScanKey cur = startKeys[i];
|
||||||
|
|
||||||
j = nKeyIs[i];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _bt_orderkeys disallows it, but it's place to add some code
|
* _bt_preprocess_keys disallows it, but it's place to add some code
|
||||||
* later
|
* later
|
||||||
*/
|
*/
|
||||||
if (so->keyData[j].sk_flags & SK_ISNULL)
|
if (cur->sk_flags & SK_ISNULL)
|
||||||
{
|
{
|
||||||
pfree(nKeyIs);
|
pfree(startKeys);
|
||||||
pfree(scankeys);
|
pfree(scankeys);
|
||||||
elog(ERROR, "btree doesn't support is(not)null, yet");
|
elog(ERROR, "btree doesn't support is(not)null, yet");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* XXX what if sk_argtype is not same as index?
|
* If scankey operator is of default subtype, we can use the
|
||||||
|
* cached comparison procedure; otherwise gotta look it up in
|
||||||
|
* the catalogs.
|
||||||
*/
|
*/
|
||||||
|
if (cur->sk_subtype == InvalidOid)
|
||||||
|
{
|
||||||
|
FmgrInfo *procinfo;
|
||||||
|
|
||||||
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
||||||
ScanKeyEntryInitializeWithInfo(scankeys + i,
|
ScanKeyEntryInitializeWithInfo(scankeys + i,
|
||||||
so->keyData[j].sk_flags,
|
cur->sk_flags,
|
||||||
i + 1,
|
i + 1,
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
|
InvalidOid,
|
||||||
procinfo,
|
procinfo,
|
||||||
so->keyData[j].sk_argument,
|
cur->sk_argument);
|
||||||
so->keyData[j].sk_argtype);
|
|
||||||
}
|
}
|
||||||
if (nKeyIs)
|
else
|
||||||
pfree(nKeyIs);
|
{
|
||||||
|
RegProcedure cmp_proc;
|
||||||
|
|
||||||
|
cmp_proc = get_opclass_proc(rel->rd_index->indclass[i],
|
||||||
|
cur->sk_subtype,
|
||||||
|
BTORDER_PROC);
|
||||||
|
ScanKeyEntryInitialize(scankeys + i,
|
||||||
|
cur->sk_flags,
|
||||||
|
i + 1,
|
||||||
|
InvalidStrategy,
|
||||||
|
cur->sk_subtype,
|
||||||
|
cmp_proc,
|
||||||
|
cur->sk_argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(startKeys);
|
||||||
|
|
||||||
current = &(scan->currentItemData);
|
current = &(scan->currentItemData);
|
||||||
|
|
||||||
|
@ -607,7 +698,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||||
*
|
*
|
||||||
* We could step forward in the latter case, but that'd be a waste of
|
* We could step forward in the latter case, but that'd be a waste of
|
||||||
* time if we want to scan backwards. So, it's now time to examine
|
* time if we want to scan backwards. So, it's now time to examine
|
||||||
* the scan strategy to find the exact place to start the scan.
|
* the initial-positioning strategy to find the exact place to start
|
||||||
|
* the scan.
|
||||||
*
|
*
|
||||||
* Note: if _bt_step fails (meaning we fell off the end of the index in
|
* Note: if _bt_step fails (meaning we fell off the end of the index in
|
||||||
* one direction or the other), we either return false (no matches) or
|
* one direction or the other), we either return false (no matches) or
|
||||||
|
@ -855,8 +947,8 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* backwards scan */
|
|
||||||
{
|
{
|
||||||
|
/* backwards scan */
|
||||||
if (offnum > P_FIRSTDATAKEY(opaque))
|
if (offnum > P_FIRSTDATAKEY(opaque))
|
||||||
offnum = OffsetNumberPrev(offnum);
|
offnum = OffsetNumberPrev(offnum);
|
||||||
else
|
else
|
||||||
|
@ -1115,7 +1207,8 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _bt_endpoint() -- Find the first or last key in the index.
|
* _bt_endpoint() -- Find the first or last key in the index, and scan
|
||||||
|
* from there to the first key satisfying all the quals.
|
||||||
*
|
*
|
||||||
* This is used by _bt_first() to set up a scan when we've determined
|
* This is used by _bt_first() to set up a scan when we've determined
|
||||||
* that the scan must start at the beginning or end of the index (for
|
* that the scan must start at the beginning or end of the index (for
|
||||||
|
@ -1205,7 +1298,9 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
||||||
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
|
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
|
||||||
itup = &(btitem->bti_itup);
|
itup = &(btitem->bti_itup);
|
||||||
|
|
||||||
/* see if we picked a winner */
|
/*
|
||||||
|
* Okay, we are on the first or last tuple. Does it pass all the quals?
|
||||||
|
*/
|
||||||
if (_bt_checkkeys(scan, itup, dir, &continuescan))
|
if (_bt_checkkeys(scan, itup, dir, &continuescan))
|
||||||
{
|
{
|
||||||
/* yes, return it */
|
/* yes, return it */
|
||||||
|
@ -1214,7 +1309,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
||||||
}
|
}
|
||||||
else if (continuescan)
|
else if (continuescan)
|
||||||
{
|
{
|
||||||
/* no, but there might be another one that is */
|
/* no, but there might be another one that does */
|
||||||
res = _bt_next(scan, dir);
|
res = _bt_next(scan, dir);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.77 2003/09/29 23:40:26 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.78 2003/11/12 21:15:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -594,33 +594,37 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
|
||||||
* Another BTSpool for dead tuples exists. Now we have to merge
|
* Another BTSpool for dead tuples exists. Now we have to merge
|
||||||
* btspool and btspool2.
|
* btspool and btspool2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* the preparation of merge */
|
||||||
|
bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
|
||||||
|
true, &should_free);
|
||||||
|
bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate,
|
||||||
|
true, &should_free2);
|
||||||
|
indexScanKey = _bt_mkscankey_nodata(index);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
load1 = true; /* load BTSpool next ? */
|
||||||
|
if (bti2 == NULL)
|
||||||
|
{
|
||||||
|
if (bti == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (bti != NULL)
|
||||||
|
{
|
||||||
|
for (i = 1; i <= keysz; i++)
|
||||||
|
{
|
||||||
ScanKey entry;
|
ScanKey entry;
|
||||||
Datum attrDatum1,
|
Datum attrDatum1,
|
||||||
attrDatum2;
|
attrDatum2;
|
||||||
bool isFirstNull,
|
bool isFirstNull,
|
||||||
isSecondNull;
|
isSecondNull;
|
||||||
int32 compare;
|
|
||||||
|
|
||||||
/* the preparation of merge */
|
|
||||||
bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free);
|
|
||||||
bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate, true, &should_free2);
|
|
||||||
indexScanKey = _bt_mkscankey_nodata(index);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
load1 = true; /* load BTSpool next ? */
|
|
||||||
if (NULL == bti2)
|
|
||||||
{
|
|
||||||
if (NULL == bti)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (NULL != bti)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (i = 1; i <= keysz; i++)
|
|
||||||
{
|
|
||||||
entry = indexScanKey + i - 1;
|
entry = indexScanKey + i - 1;
|
||||||
attrDatum1 = index_getattr((IndexTuple) bti, i, tupdes, &isFirstNull);
|
attrDatum1 = index_getattr((IndexTuple) bti, i, tupdes,
|
||||||
attrDatum2 = index_getattr((IndexTuple) bti2, i, tupdes, &isSecondNull);
|
&isFirstNull);
|
||||||
|
attrDatum2 = index_getattr((IndexTuple) bti2, i, tupdes,
|
||||||
|
&isSecondNull);
|
||||||
if (isFirstNull)
|
if (isFirstNull)
|
||||||
{
|
{
|
||||||
if (!isSecondNull)
|
if (!isSecondNull)
|
||||||
|
@ -633,7 +637,11 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
compare = DatumGetInt32(FunctionCall2(&entry->sk_func, attrDatum1, attrDatum2));
|
int32 compare;
|
||||||
|
|
||||||
|
compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
|
||||||
|
attrDatum1,
|
||||||
|
attrDatum2));
|
||||||
if (compare > 0)
|
if (compare > 0)
|
||||||
{
|
{
|
||||||
load1 = false;
|
load1 = false;
|
||||||
|
@ -656,14 +664,16 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
|
||||||
_bt_buildadd(index, state, bti);
|
_bt_buildadd(index, state, bti);
|
||||||
if (should_free)
|
if (should_free)
|
||||||
pfree((void *) bti);
|
pfree((void *) bti);
|
||||||
bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free);
|
bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
|
||||||
|
true, &should_free);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_bt_buildadd(index, state, bti2);
|
_bt_buildadd(index, state, bti2);
|
||||||
if (should_free2)
|
if (should_free2)
|
||||||
pfree((void *) bti2);
|
pfree((void *) bti2);
|
||||||
bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate, true, &should_free2);
|
bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate,
|
||||||
|
true, &should_free2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_bt_freeskey(indexScanKey);
|
_bt_freeskey(indexScanKey);
|
||||||
|
@ -671,7 +681,8 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* merge is unnecessary */
|
/* merge is unnecessary */
|
||||||
while (bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free), bti != (BTItem) NULL)
|
while ((bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
|
||||||
|
true, &should_free)) != NULL)
|
||||||
{
|
{
|
||||||
/* When we see first tuple, create first index page */
|
/* When we see first tuple, create first index page */
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.55 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.56 2003/11/12 21:15:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "executor/execdebug.h"
|
#include "executor/execdebug.h"
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,8 +48,8 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
||||||
bool null;
|
bool null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can use the cached support procs since no cross-type comparison
|
* We can use the cached (default) support procs since no cross-type
|
||||||
* can be needed.
|
* comparison can be needed.
|
||||||
*/
|
*/
|
||||||
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
||||||
arg = index_getattr(itup, i + 1, itupdesc, &null);
|
arg = index_getattr(itup, i + 1, itupdesc, &null);
|
||||||
|
@ -58,9 +57,9 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
||||||
null ? SK_ISNULL : 0,
|
null ? SK_ISNULL : 0,
|
||||||
(AttrNumber) (i + 1),
|
(AttrNumber) (i + 1),
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
|
InvalidOid,
|
||||||
procinfo,
|
procinfo,
|
||||||
arg,
|
arg);
|
||||||
itupdesc->attrs[i]->atttypid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return skey;
|
return skey;
|
||||||
|
@ -94,17 +93,17 @@ _bt_mkscankey_nodata(Relation rel)
|
||||||
FmgrInfo *procinfo;
|
FmgrInfo *procinfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can use the cached support procs since no cross-type comparison
|
* We can use the cached (default) support procs since no cross-type
|
||||||
* can be needed.
|
* comparison can be needed.
|
||||||
*/
|
*/
|
||||||
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
||||||
ScanKeyEntryInitializeWithInfo(&skey[i],
|
ScanKeyEntryInitializeWithInfo(&skey[i],
|
||||||
SK_ISNULL,
|
SK_ISNULL,
|
||||||
(AttrNumber) (i + 1),
|
(AttrNumber) (i + 1),
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
|
InvalidOid,
|
||||||
procinfo,
|
procinfo,
|
||||||
(Datum) 0,
|
(Datum) 0);
|
||||||
itupdesc->attrs[i]->atttypid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return skey;
|
return skey;
|
||||||
|
@ -161,105 +160,104 @@ _bt_formitem(IndexTuple itup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------
|
/*----------
|
||||||
* _bt_orderkeys() -- Put keys in a sensible order for conjunctive quals.
|
* _bt_preprocess_keys() -- Preprocess scan keys
|
||||||
*
|
*
|
||||||
* After this routine runs, the scan keys are ordered by index attribute
|
* The caller-supplied keys (in scan->keyData[]) are copied to
|
||||||
* (all quals for attr 1, then all for attr 2, etc) and within each attr
|
* so->keyData[] with possible transformation. scan->numberOfKeys is
|
||||||
* the keys are ordered by constraint type: ">", ">=", "=", "<=", "<".
|
* the number of input keys, so->numberOfKeys gets the number of output
|
||||||
* Furthermore, redundant keys are eliminated: we keep only the tightest
|
* keys (possibly less, never greater).
|
||||||
* >/>= bound and the tightest </<= bound, and if there's an = key then
|
|
||||||
* that's the only one returned. (So, we return either a single = key,
|
|
||||||
* or one or two boundary-condition keys for each attr.)
|
|
||||||
*
|
*
|
||||||
* As a byproduct of this work, we can detect contradictory quals such
|
* The primary purpose of this routine is to discover how many scan keys
|
||||||
* as "x = 1 AND x > 2". If we see that, we return so->quals_ok = FALSE,
|
* must be satisfied to continue the scan. It also attempts to eliminate
|
||||||
* indicating the scan need not be run at all since no tuples can match.
|
* redundant keys and detect contradictory keys. At present, redundant and
|
||||||
|
* contradictory keys can only be detected for same-data-type comparisons,
|
||||||
|
* but that's the usual case so it seems worth doing.
|
||||||
*
|
*
|
||||||
* Another byproduct is to determine how many quals must be satisfied to
|
* The output keys must be sorted by index attribute. Presently we expect
|
||||||
|
* (but verify) that the input keys are already so sorted --- this is done
|
||||||
|
* by group_clauses_by_indexkey() in indxpath.c. Some reordering of the keys
|
||||||
|
* within each attribute may be done as a byproduct of the processing here,
|
||||||
|
* but no other code depends on that.
|
||||||
|
*
|
||||||
|
* Aside from preparing so->keyData[], this routine sets
|
||||||
|
* so->numberOfRequiredKeys to the number of quals that must be satisfied to
|
||||||
* continue the scan. _bt_checkkeys uses this. For example, if the quals
|
* continue the scan. _bt_checkkeys uses this. For example, if the quals
|
||||||
* are "x = 1 AND y < 4 AND z < 5", then _bt_checkkeys will reject a tuple
|
* are "x = 1 AND y < 4 AND z < 5", then _bt_checkkeys will reject a tuple
|
||||||
* (1,2,7), but we must continue the scan in case there are tuples (1,3,z).
|
* (1,2,7), but we must continue the scan in case there are tuples (1,3,z).
|
||||||
* But once we reach tuples like (1,4,z) we can stop scanning because no
|
* But once we reach tuples like (1,4,z) we can stop scanning because no
|
||||||
* later tuples could match. This is reflected by setting
|
* later tuples could match. This is reflected by setting
|
||||||
* so->numberOfRequiredKeys to the number of leading keys that must be
|
* so->numberOfRequiredKeys to 2, the number of leading keys that must be
|
||||||
* matched to continue the scan. numberOfRequiredKeys is equal to the
|
* matched to continue the scan. In general, numberOfRequiredKeys is equal
|
||||||
* number of leading "=" keys plus the key(s) for the first non "="
|
* to the number of keys for leading attributes with "=" keys, plus the
|
||||||
* attribute, which can be seen to be correct by considering the above
|
* key(s) for the first non "=" attribute, which can be seen to be correct
|
||||||
* example.
|
* by considering the above example.
|
||||||
|
*
|
||||||
|
* If possible, redundant keys are eliminated: we keep only the tightest
|
||||||
|
* >/>= bound and the tightest </<= bound, and if there's an = key then
|
||||||
|
* that's the only one returned. (So, we return either a single = key,
|
||||||
|
* or one or two boundary-condition keys for each attr.) However, we can
|
||||||
|
* only detect redundant keys when the right-hand datatypes are all equal
|
||||||
|
* to the index datatype, because we do not know suitable operators for
|
||||||
|
* comparing right-hand values of two different datatypes. (In theory
|
||||||
|
* we could handle comparison of a RHS of the index datatype with a RHS of
|
||||||
|
* another type, but that seems too much pain for too little gain.) So,
|
||||||
|
* keys whose operator has a nondefault subtype (ie, its RHS is not of the
|
||||||
|
* index datatype) are ignored here, except for noting whether they impose
|
||||||
|
* an "=" condition or not.
|
||||||
|
*
|
||||||
|
* As a byproduct of this work, we can detect contradictory quals such
|
||||||
|
* as "x = 1 AND x > 2". If we see that, we return so->quals_ok = FALSE,
|
||||||
|
* indicating the scan need not be run at all since no tuples can match.
|
||||||
|
* Again though, only keys with RHS datatype equal to the index datatype
|
||||||
|
* can be checked for contradictions.
|
||||||
*
|
*
|
||||||
* Furthermore, we detect the case where the index is unique and we have
|
* Furthermore, we detect the case where the index is unique and we have
|
||||||
* equality quals for all columns. In this case there can be at most one
|
* equality quals for all columns. In this case there can be at most one
|
||||||
* (visible) matching tuple. index_getnext uses this to avoid uselessly
|
* (visible) matching tuple. index_getnext uses this to avoid uselessly
|
||||||
* continuing the scan after finding one match.
|
* continuing the scan after finding one match.
|
||||||
*
|
|
||||||
* The initial ordering of the keys is expected to be by attribute already
|
|
||||||
* (see group_clauses_by_indexkey() in indxpath.c). The task here is to
|
|
||||||
* standardize the appearance of multiple keys for the same attribute.
|
|
||||||
*----------
|
*----------
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_bt_orderkeys(IndexScanDesc scan)
|
_bt_preprocess_keys(IndexScanDesc scan)
|
||||||
{
|
{
|
||||||
Relation relation = scan->indexRelation;
|
Relation relation = scan->indexRelation;
|
||||||
BTScanOpaque so = (BTScanOpaque) scan->opaque;
|
BTScanOpaque so = (BTScanOpaque) scan->opaque;
|
||||||
ScanKeyData xform[BTMaxStrategyNumber];
|
int numberOfKeys = scan->numberOfKeys;
|
||||||
bool init[BTMaxStrategyNumber];
|
int new_numberOfKeys;
|
||||||
int numberOfKeys = so->numberOfKeys;
|
ScanKey inkeys;
|
||||||
ScanKey key;
|
ScanKey outkeys;
|
||||||
ScanKey cur;
|
ScanKey cur;
|
||||||
|
ScanKey xform[BTMaxStrategyNumber];
|
||||||
|
bool allEqualSoFar;
|
||||||
|
bool hasOtherTypeEqual;
|
||||||
Datum test;
|
Datum test;
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
AttrNumber attno;
|
AttrNumber attno;
|
||||||
int new_numberOfKeys;
|
|
||||||
bool allEqualSoFar;
|
|
||||||
|
|
||||||
|
/* initialize result variables */
|
||||||
so->qual_ok = true;
|
so->qual_ok = true;
|
||||||
|
so->numberOfKeys = 0;
|
||||||
so->numberOfRequiredKeys = 0;
|
so->numberOfRequiredKeys = 0;
|
||||||
scan->keys_are_unique = false;
|
scan->keys_are_unique = false;
|
||||||
|
|
||||||
if (numberOfKeys < 1)
|
if (numberOfKeys < 1)
|
||||||
return; /* done if qual-less scan */
|
return; /* done if qual-less scan */
|
||||||
|
|
||||||
key = so->keyData;
|
inkeys = scan->keyData;
|
||||||
cur = &key[0];
|
outkeys = so->keyData;
|
||||||
/* check input keys are correctly ordered */
|
cur = &inkeys[0];
|
||||||
|
/* we check that input keys are correctly ordered */
|
||||||
if (cur->sk_attno != 1)
|
if (cur->sk_attno != 1)
|
||||||
elog(ERROR, "key(s) for attribute 1 missed");
|
elog(ERROR, "key(s) for attribute 1 missed");
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* XXX verify that operator strategy info is correct */
|
|
||||||
/* XXX this is temporary for debugging; it's pretty expensive */
|
|
||||||
/* XXX can't do it during bootstrap, else will recurse infinitely */
|
|
||||||
{
|
|
||||||
extern bool criticalRelcachesBuilt;
|
|
||||||
static bool inRecursion = false;
|
|
||||||
|
|
||||||
if (criticalRelcachesBuilt && !inRecursion)
|
|
||||||
{
|
|
||||||
inRecursion = true;
|
|
||||||
for (i = 0; i < numberOfKeys; i++)
|
|
||||||
{
|
|
||||||
AttrNumber attno = key[i].sk_attno;
|
|
||||||
Oid opclass;
|
|
||||||
Oid chk_oper;
|
|
||||||
|
|
||||||
opclass = relation->rd_index->indclass[attno-1];
|
|
||||||
chk_oper = get_opclass_member(opclass, key[i].sk_strategy);
|
|
||||||
Assert(key[i].sk_func.fn_oid == get_opcode(chk_oper));
|
|
||||||
}
|
|
||||||
inRecursion = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We can short-circuit most of the work if there's just one key */
|
/* We can short-circuit most of the work if there's just one key */
|
||||||
if (numberOfKeys == 1)
|
if (numberOfKeys == 1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We don't use indices for 'A is null' and 'A is not null'
|
* We don't use indices for 'A is null' and 'A is not null'
|
||||||
* currently and 'A < = > <> NULL' will always fail - so qual is
|
* currently and 'A < = > <> NULL' will always fail - so qual is
|
||||||
* not Ok if comparison value is NULL. - vadim 03/21/97
|
* not OK if comparison value is NULL. - vadim 03/21/97
|
||||||
*/
|
*/
|
||||||
if (cur->sk_flags & SK_ISNULL)
|
if (cur->sk_flags & SK_ISNULL)
|
||||||
so->qual_ok = false;
|
so->qual_ok = false;
|
||||||
|
@ -270,6 +268,8 @@ _bt_orderkeys(IndexScanDesc scan)
|
||||||
if (cur->sk_strategy == BTEqualStrategyNumber)
|
if (cur->sk_strategy == BTEqualStrategyNumber)
|
||||||
scan->keys_are_unique = true;
|
scan->keys_are_unique = true;
|
||||||
}
|
}
|
||||||
|
memcpy(outkeys, inkeys, sizeof(ScanKeyData));
|
||||||
|
so->numberOfKeys = 1;
|
||||||
so->numberOfRequiredKeys = 1;
|
so->numberOfRequiredKeys = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -283,12 +283,15 @@ _bt_orderkeys(IndexScanDesc scan)
|
||||||
/*
|
/*
|
||||||
* Initialize for processing of keys for attr 1.
|
* Initialize for processing of keys for attr 1.
|
||||||
*
|
*
|
||||||
* xform[i] holds a copy of the current scan key of strategy type i+1, if
|
* xform[i] points to the currently best scan key of strategy type i+1,
|
||||||
* any; init[i] is TRUE if we have found such a key for this attr.
|
* if any is found with a default operator subtype; it is NULL if we
|
||||||
|
* haven't yet found such a key for this attr. Scan keys of nondefault
|
||||||
|
* subtypes are transferred to the output with no processing except for
|
||||||
|
* noting if they are of "=" type.
|
||||||
*/
|
*/
|
||||||
attno = 1;
|
attno = 1;
|
||||||
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
memset(xform, 0, sizeof(xform));
|
||||||
MemSet(init, 0, sizeof(init));
|
hasOtherTypeEqual = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop iterates from 0 to numberOfKeys inclusive; we use the last
|
* Loop iterates from 0 to numberOfKeys inclusive; we use the last
|
||||||
|
@ -329,80 +332,78 @@ _bt_orderkeys(IndexScanDesc scan)
|
||||||
* of key > 2 && key == 1 and so on we have to set qual_ok to
|
* of key > 2 && key == 1 and so on we have to set qual_ok to
|
||||||
* false before discarding the other keys.
|
* false before discarding the other keys.
|
||||||
*/
|
*/
|
||||||
if (init[BTEqualStrategyNumber - 1])
|
if (xform[BTEqualStrategyNumber - 1])
|
||||||
{
|
{
|
||||||
ScanKeyData *eq,
|
ScanKey eq = xform[BTEqualStrategyNumber - 1];
|
||||||
*chk;
|
|
||||||
|
|
||||||
eq = &xform[BTEqualStrategyNumber - 1];
|
|
||||||
for (j = BTMaxStrategyNumber; --j >= 0;)
|
for (j = BTMaxStrategyNumber; --j >= 0;)
|
||||||
{
|
{
|
||||||
if (!init[j] ||
|
ScanKey chk = xform[j];
|
||||||
j == (BTEqualStrategyNumber - 1))
|
|
||||||
|
if (!chk || j == (BTEqualStrategyNumber - 1))
|
||||||
continue;
|
continue;
|
||||||
chk = &xform[j];
|
|
||||||
test = FunctionCall2(&chk->sk_func,
|
test = FunctionCall2(&chk->sk_func,
|
||||||
eq->sk_argument,
|
eq->sk_argument,
|
||||||
chk->sk_argument);
|
chk->sk_argument);
|
||||||
if (!DatumGetBool(test))
|
if (!DatumGetBool(test))
|
||||||
|
{
|
||||||
so->qual_ok = false;
|
so->qual_ok = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
init[BTLessStrategyNumber - 1] = false;
|
}
|
||||||
init[BTLessEqualStrategyNumber - 1] = false;
|
xform[BTLessStrategyNumber - 1] = NULL;
|
||||||
init[BTGreaterEqualStrategyNumber - 1] = false;
|
xform[BTLessEqualStrategyNumber - 1] = NULL;
|
||||||
init[BTGreaterStrategyNumber - 1] = false;
|
xform[BTGreaterEqualStrategyNumber - 1] = NULL;
|
||||||
|
xform[BTGreaterStrategyNumber - 1] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* No "=" for this key, so we're done with required keys
|
* If no "=" for this key, we're done with required keys
|
||||||
*/
|
*/
|
||||||
|
if (! hasOtherTypeEqual)
|
||||||
allEqualSoFar = false;
|
allEqualSoFar = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep only one of <, <= */
|
/* keep only one of <, <= */
|
||||||
if (init[BTLessStrategyNumber - 1]
|
if (xform[BTLessStrategyNumber - 1]
|
||||||
&& init[BTLessEqualStrategyNumber - 1])
|
&& xform[BTLessEqualStrategyNumber - 1])
|
||||||
{
|
{
|
||||||
ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];
|
ScanKey lt = xform[BTLessStrategyNumber - 1];
|
||||||
ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];
|
ScanKey le = xform[BTLessEqualStrategyNumber - 1];
|
||||||
|
|
||||||
test = FunctionCall2(&le->sk_func,
|
test = FunctionCall2(&le->sk_func,
|
||||||
lt->sk_argument,
|
lt->sk_argument,
|
||||||
le->sk_argument);
|
le->sk_argument);
|
||||||
if (DatumGetBool(test))
|
if (DatumGetBool(test))
|
||||||
init[BTLessEqualStrategyNumber - 1] = false;
|
xform[BTLessEqualStrategyNumber - 1] = NULL;
|
||||||
else
|
else
|
||||||
init[BTLessStrategyNumber - 1] = false;
|
xform[BTLessStrategyNumber - 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep only one of >, >= */
|
/* keep only one of >, >= */
|
||||||
if (init[BTGreaterStrategyNumber - 1]
|
if (xform[BTGreaterStrategyNumber - 1]
|
||||||
&& init[BTGreaterEqualStrategyNumber - 1])
|
&& xform[BTGreaterEqualStrategyNumber - 1])
|
||||||
{
|
{
|
||||||
ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];
|
ScanKey gt = xform[BTGreaterStrategyNumber - 1];
|
||||||
ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];
|
ScanKey ge = xform[BTGreaterEqualStrategyNumber - 1];
|
||||||
|
|
||||||
test = FunctionCall2(&ge->sk_func,
|
test = FunctionCall2(&ge->sk_func,
|
||||||
gt->sk_argument,
|
gt->sk_argument,
|
||||||
ge->sk_argument);
|
ge->sk_argument);
|
||||||
if (DatumGetBool(test))
|
if (DatumGetBool(test))
|
||||||
init[BTGreaterEqualStrategyNumber - 1] = false;
|
xform[BTGreaterEqualStrategyNumber - 1] = NULL;
|
||||||
else
|
else
|
||||||
init[BTGreaterStrategyNumber - 1] = false;
|
xform[BTGreaterStrategyNumber - 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emit the cleaned-up keys back into the key[] array in the
|
* Emit the cleaned-up keys into the outkeys[] array.
|
||||||
* correct order. Note we are overwriting our input here!
|
|
||||||
* It's OK because (a) xform[] is a physical copy of the keys
|
|
||||||
* we want, (b) we cannot emit more keys than we input, so we
|
|
||||||
* won't overwrite as-yet-unprocessed keys.
|
|
||||||
*/
|
*/
|
||||||
for (j = BTMaxStrategyNumber; --j >= 0;)
|
for (j = BTMaxStrategyNumber; --j >= 0;)
|
||||||
{
|
{
|
||||||
if (init[j])
|
if (xform[j])
|
||||||
memcpy(&key[new_numberOfKeys++], &xform[j],
|
memcpy(&outkeys[new_numberOfKeys++], xform[j],
|
||||||
sizeof(ScanKeyData));
|
sizeof(ScanKeyData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,31 +422,43 @@ _bt_orderkeys(IndexScanDesc scan)
|
||||||
|
|
||||||
/* Re-initialize for new attno */
|
/* Re-initialize for new attno */
|
||||||
attno = cur->sk_attno;
|
attno = cur->sk_attno;
|
||||||
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
memset(xform, 0, sizeof(xform));
|
||||||
MemSet(init, 0, sizeof(init));
|
hasOtherTypeEqual = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* figure out which strategy this key's operator corresponds to */
|
/* check strategy this key's operator corresponds to */
|
||||||
j = cur->sk_strategy - 1;
|
j = cur->sk_strategy - 1;
|
||||||
|
|
||||||
/* have we seen one of these before? */
|
/* if wrong RHS data type, punt */
|
||||||
if (init[j])
|
if (cur->sk_subtype != InvalidOid)
|
||||||
{
|
{
|
||||||
/* yup, keep the more restrictive value */
|
memcpy(&outkeys[new_numberOfKeys++], cur,
|
||||||
|
sizeof(ScanKeyData));
|
||||||
|
if (j == (BTEqualStrategyNumber - 1))
|
||||||
|
hasOtherTypeEqual = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* have we seen one of these before? */
|
||||||
|
if (xform[j])
|
||||||
|
{
|
||||||
|
/* yup, keep the more restrictive key */
|
||||||
test = FunctionCall2(&cur->sk_func,
|
test = FunctionCall2(&cur->sk_func,
|
||||||
cur->sk_argument,
|
cur->sk_argument,
|
||||||
xform[j].sk_argument);
|
xform[j]->sk_argument);
|
||||||
if (DatumGetBool(test))
|
if (DatumGetBool(test))
|
||||||
xform[j].sk_argument = cur->sk_argument;
|
xform[j] = cur;
|
||||||
else if (j == (BTEqualStrategyNumber - 1))
|
else if (j == (BTEqualStrategyNumber - 1))
|
||||||
so->qual_ok = false;
|
{
|
||||||
/* key == a && key == b, but a != b */
|
/* key == a && key == b, but a != b */
|
||||||
|
so->qual_ok = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* nope, so remember this scankey */
|
/* nope, so remember this scankey */
|
||||||
memcpy(&xform[j], cur, sizeof(ScanKeyData));
|
xform[j] = cur;
|
||||||
init[j] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,8 +478,8 @@ _bt_orderkeys(IndexScanDesc scan)
|
||||||
*
|
*
|
||||||
* If the tuple fails to pass the qual, we also determine whether there's
|
* If the tuple fails to pass the qual, we also determine whether there's
|
||||||
* any need to continue the scan beyond this tuple, and set *continuescan
|
* any need to continue the scan beyond this tuple, and set *continuescan
|
||||||
* accordingly. See comments for _bt_orderkeys(), above, about how this is
|
* accordingly. See comments for _bt_preprocess_keys(), above, about how
|
||||||
* done.
|
* this is done.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
|
@ -474,7 +487,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
{
|
{
|
||||||
BTScanOpaque so = (BTScanOpaque) scan->opaque;
|
BTScanOpaque so = (BTScanOpaque) scan->opaque;
|
||||||
int keysz = so->numberOfKeys;
|
int keysz = so->numberOfKeys;
|
||||||
int keysok;
|
int ikey;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
ScanKey key;
|
ScanKey key;
|
||||||
|
|
||||||
|
@ -484,13 +497,11 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
if (keysz == 0)
|
if (keysz == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
tupdesc = RelationGetDescr(scan->indexRelation);
|
|
||||||
key = so->keyData;
|
|
||||||
keysok = 0;
|
|
||||||
|
|
||||||
IncrIndexProcessed();
|
IncrIndexProcessed();
|
||||||
|
|
||||||
while (keysz > 0)
|
tupdesc = RelationGetDescr(scan->indexRelation);
|
||||||
|
|
||||||
|
for (key = so->keyData, ikey = 0; ikey < keysz; key++, ikey++)
|
||||||
{
|
{
|
||||||
Datum datum;
|
Datum datum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
@ -504,7 +515,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
/* btree doesn't support 'A is null' clauses, yet */
|
/* btree doesn't support 'A is null' clauses, yet */
|
||||||
if (key->sk_flags & SK_ISNULL)
|
if (key->sk_flags & SK_ISNULL)
|
||||||
{
|
{
|
||||||
/* we shouldn't get here, really; see _bt_orderkeys() */
|
/* we shouldn't get here, really; see _bt_preprocess_keys() */
|
||||||
*continuescan = false;
|
*continuescan = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -518,7 +529,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
* one of the "must match" subset. On a backward scan,
|
* one of the "must match" subset. On a backward scan,
|
||||||
* however, we should keep going.
|
* however, we should keep going.
|
||||||
*/
|
*/
|
||||||
if (keysok < so->numberOfRequiredKeys &&
|
if (ikey < so->numberOfRequiredKeys &&
|
||||||
ScanDirectionIsForward(dir))
|
ScanDirectionIsForward(dir))
|
||||||
*continuescan = false;
|
*continuescan = false;
|
||||||
|
|
||||||
|
@ -534,16 +545,50 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Tuple fails this qual. If it's a required qual, then we
|
* Tuple fails this qual. If it's a required qual, then we
|
||||||
* can conclude no further tuples will pass, either.
|
* may be able to conclude no further tuples will pass, either.
|
||||||
|
* We have to look at the scan direction and the qual type.
|
||||||
|
*
|
||||||
|
* Note: the only case in which we would keep going after failing
|
||||||
|
* a required qual is if there are partially-redundant quals that
|
||||||
|
* _bt_preprocess_keys() was unable to eliminate. For example,
|
||||||
|
* given "x > 4 AND x > 10" where both are cross-type comparisons
|
||||||
|
* and so not removable, we might start the scan at the x = 4
|
||||||
|
* boundary point. The "x > 10" condition will fail until we
|
||||||
|
* pass x = 10, but we must not stop the scan on its account.
|
||||||
|
*
|
||||||
|
* Note: because we stop the scan as soon as any required equality
|
||||||
|
* qual fails, it is critical that equality quals be used for the
|
||||||
|
* initial positioning in _bt_first() when they are available.
|
||||||
|
* See comments in _bt_first().
|
||||||
*/
|
*/
|
||||||
if (keysok < so->numberOfRequiredKeys)
|
if (ikey < so->numberOfRequiredKeys)
|
||||||
|
{
|
||||||
|
switch (key->sk_strategy)
|
||||||
|
{
|
||||||
|
case BTLessStrategyNumber:
|
||||||
|
case BTLessEqualStrategyNumber:
|
||||||
|
if (ScanDirectionIsForward(dir))
|
||||||
*continuescan = false;
|
*continuescan = false;
|
||||||
return false;
|
break;
|
||||||
|
case BTEqualStrategyNumber:
|
||||||
|
*continuescan = false;
|
||||||
|
break;
|
||||||
|
case BTGreaterEqualStrategyNumber:
|
||||||
|
case BTGreaterStrategyNumber:
|
||||||
|
if (ScanDirectionIsBackward(dir))
|
||||||
|
*continuescan = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unrecognized StrategyNumber: %d",
|
||||||
|
key->sk_strategy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keysok++;
|
/*
|
||||||
key++;
|
* In any case, this indextuple doesn't match the qual.
|
||||||
keysz--;
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, the tuple passes all quals. */
|
/* If we get here, the tuple passes all quals. */
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.37 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.38 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -82,20 +82,6 @@ rt_box_size(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* rt_bigbox_size() -- Compute a size for big boxes.
|
|
||||||
*
|
|
||||||
* In an earlier release of the system, this routine did something
|
|
||||||
* different from rt_box_size. We now use floats, rather than ints,
|
|
||||||
* as the return type for the size routine, so we no longer need to
|
|
||||||
* have a special return type for big boxes.
|
|
||||||
*/
|
|
||||||
Datum
|
|
||||||
rt_bigbox_size(PG_FUNCTION_ARGS)
|
|
||||||
{
|
|
||||||
return rt_box_size(fcinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
rt_poly_union(PG_FUNCTION_ARGS)
|
rt_poly_union(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.49 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -123,15 +123,17 @@ rtrescan(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
opclass = s->indexRelation->rd_index->indclass[attno-1];
|
opclass = s->indexRelation->rd_index->indclass[attno-1];
|
||||||
int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
|
int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
|
||||||
int_oper = get_opclass_member(opclass, int_strategy);
|
int_oper = get_opclass_member(opclass,
|
||||||
|
s->keyData[i].sk_subtype,
|
||||||
|
int_strategy);
|
||||||
int_proc = get_opcode(int_oper);
|
int_proc = get_opcode(int_oper);
|
||||||
ScanKeyEntryInitialize(&(p->s_internalKey[i]),
|
ScanKeyEntryInitialize(&(p->s_internalKey[i]),
|
||||||
s->keyData[i].sk_flags,
|
s->keyData[i].sk_flags,
|
||||||
attno,
|
attno,
|
||||||
int_strategy,
|
int_strategy,
|
||||||
|
s->keyData[i].sk_subtype,
|
||||||
int_proc,
|
int_proc,
|
||||||
s->keyData[i].sk_argument,
|
s->keyData[i].sk_argument);
|
||||||
s->keyData[i].sk_argtype);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.92 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.93 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
|
@ -366,10 +366,10 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
||||||
char replaces[Natts_pg_database];
|
char replaces[Natts_pg_database];
|
||||||
|
|
||||||
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(dbname), NAMEOID);
|
CStringGetDatum(dbname));
|
||||||
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
||||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
@ -1131,10 +1131,10 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
|
||||||
* There's no syscache for pg_database, so must look the hard way
|
* There's no syscache for pg_database, so must look the hard way
|
||||||
*/
|
*/
|
||||||
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(db_oid), OIDOID);
|
ObjectIdGetDatum(db_oid));
|
||||||
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
||||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
@ -1531,10 +1531,10 @@ pg_database_ownercheck(Oid db_oid, AclId userid)
|
||||||
|
|
||||||
/* There's no syscache for pg_database, so must look the hard way */
|
/* There's no syscache for pg_database, so must look the hard way */
|
||||||
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(db_oid), OIDOID);
|
ObjectIdGetDatum(db_oid));
|
||||||
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
||||||
|
|
||||||
dbtuple = heap_getnext(scan, ForwardScanDirection);
|
dbtuple = heap_getnext(scan, ForwardScanDirection);
|
||||||
|
|
|
@ -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
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.32 2003/11/09 21:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.33 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/proclang.h"
|
#include "commands/proclang.h"
|
||||||
|
@ -283,20 +282,20 @@ findAutoDeletableObjects(const ObjectAddress *object,
|
||||||
* When dropping a whole object (subId = 0), find pg_depend records for
|
* When dropping a whole object (subId = 0), find pg_depend records for
|
||||||
* its sub-objects too.
|
* its sub-objects too.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_refclassid,
|
Anum_pg_depend_refclassid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->classId), OIDOID);
|
ObjectIdGetDatum(object->classId));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_refobjid,
|
Anum_pg_depend_refobjid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId), OIDOID);
|
ObjectIdGetDatum(object->objectId));
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0,
|
ScanKeyInit(&key[2],
|
||||||
Anum_pg_depend_refobjsubid,
|
Anum_pg_depend_refobjsubid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(object->objectSubId), INT4OID);
|
Int32GetDatum(object->objectSubId));
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -418,20 +417,20 @@ recursiveDeletion(const ObjectAddress *object,
|
||||||
* When dropping a whole object (subId = 0), remove all pg_depend records
|
* When dropping a whole object (subId = 0), remove all pg_depend records
|
||||||
* for its sub-objects too.
|
* for its sub-objects too.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_classid,
|
Anum_pg_depend_classid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->classId), OIDOID);
|
ObjectIdGetDatum(object->classId));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_objid,
|
Anum_pg_depend_objid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId), OIDOID);
|
ObjectIdGetDatum(object->objectId));
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0,
|
ScanKeyInit(&key[2],
|
||||||
Anum_pg_depend_objsubid,
|
Anum_pg_depend_objsubid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(object->objectSubId), INT4OID);
|
Int32GetDatum(object->objectSubId));
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -651,20 +650,20 @@ deleteDependentObjects(const ObjectAddress *object,
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
ObjectAddress otherObject;
|
ObjectAddress otherObject;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_refclassid,
|
Anum_pg_depend_refclassid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->classId), OIDOID);
|
ObjectIdGetDatum(object->classId));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_refobjid,
|
Anum_pg_depend_refobjid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId), OIDOID);
|
ObjectIdGetDatum(object->objectId));
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0,
|
ScanKeyInit(&key[2],
|
||||||
Anum_pg_depend_refobjsubid,
|
Anum_pg_depend_refobjsubid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(object->objectSubId), INT4OID);
|
Int32GetDatum(object->objectSubId));
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1473,11 +1472,10 @@ getObjectDescription(const ObjectAddress *object)
|
||||||
|
|
||||||
castDesc = heap_openr(CastRelationName, AccessShareLock);
|
castDesc = heap_openr(CastRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId),
|
ObjectIdGetDatum(object->objectId));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
rcscan = systable_beginscan(castDesc, CastOidIndex, true,
|
rcscan = systable_beginscan(castDesc, CastOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -1509,11 +1507,10 @@ getObjectDescription(const ObjectAddress *object)
|
||||||
|
|
||||||
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId),
|
ObjectIdGetDatum(object->objectId));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -1570,11 +1567,10 @@ getObjectDescription(const ObjectAddress *object)
|
||||||
|
|
||||||
attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId),
|
ObjectIdGetDatum(object->objectId));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex,
|
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex,
|
||||||
true, SnapshotNow, 1, skey);
|
true, SnapshotNow, 1, skey);
|
||||||
|
@ -1672,11 +1668,10 @@ getObjectDescription(const ObjectAddress *object)
|
||||||
|
|
||||||
ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
|
ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId),
|
ObjectIdGetDatum(object->objectId));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
|
rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -1708,11 +1703,10 @@ getObjectDescription(const ObjectAddress *object)
|
||||||
|
|
||||||
trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
|
trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId),
|
ObjectIdGetDatum(object->objectId));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
tgscan = systable_beginscan(trigDesc, TriggerOidIndex, true,
|
tgscan = systable_beginscan(trigDesc, TriggerOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.254 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.255 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
|
@ -853,11 +853,10 @@ RelationRemoveInheritance(Relation relation)
|
||||||
|
|
||||||
catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
|
catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_inherits_inhrelid,
|
Anum_pg_inherits_inhrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
|
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
|
@ -920,10 +919,10 @@ DeleteAttributeTuples(Oid relid)
|
||||||
attrel = heap_openr(AttributeRelationName, RowExclusiveLock);
|
attrel = heap_openr(AttributeRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/* Use the index to scan only attributes of the target relation */
|
/* Use the index to scan only attributes of the target relation */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_attribute_attrelid,
|
Anum_pg_attribute_attrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
scan = systable_beginscan(attrel, AttributeRelidNumIndex, true,
|
scan = systable_beginscan(attrel, AttributeRelidNumIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
|
@ -1035,14 +1034,14 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
|
||||||
|
|
||||||
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scankeys[0], 0,
|
ScanKeyInit(&scankeys[0],
|
||||||
Anum_pg_attrdef_adrelid,
|
Anum_pg_attrdef_adrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
ScanKeyEntryInitialize(&scankeys[1], 0,
|
ScanKeyInit(&scankeys[1],
|
||||||
Anum_pg_attrdef_adnum,
|
Anum_pg_attrdef_adnum,
|
||||||
BTEqualStrategyNumber, F_INT2EQ,
|
BTEqualStrategyNumber, F_INT2EQ,
|
||||||
Int16GetDatum(attnum), INT2OID);
|
Int16GetDatum(attnum));
|
||||||
|
|
||||||
scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
|
scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
|
||||||
SnapshotNow, 2, scankeys);
|
SnapshotNow, 2, scankeys);
|
||||||
|
@ -1092,10 +1091,10 @@ RemoveAttrDefaultById(Oid attrdefId)
|
||||||
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/* Find the pg_attrdef tuple */
|
/* Find the pg_attrdef tuple */
|
||||||
ScanKeyEntryInitialize(&scankeys[0], 0,
|
ScanKeyInit(&scankeys[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(attrdefId), OIDOID);
|
ObjectIdGetDatum(attrdefId));
|
||||||
|
|
||||||
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true,
|
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true,
|
||||||
SnapshotNow, 1, scankeys);
|
SnapshotNow, 1, scankeys);
|
||||||
|
@ -1829,10 +1828,10 @@ RemoveRelConstraints(Relation rel, const char *constrName,
|
||||||
conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/* Use the index to scan only constraints of the target relation */
|
/* Use the index to scan only constraints of the target relation */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_constraint_conrelid,
|
Anum_pg_constraint_conrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||||
|
|
||||||
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
|
@ -1883,19 +1882,19 @@ RemoveStatistics(Relation rel, AttrNumber attnum)
|
||||||
|
|
||||||
pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
|
pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_statistic_starelid,
|
Anum_pg_statistic_starelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||||
|
|
||||||
if (attnum == 0)
|
if (attnum == 0)
|
||||||
nkeys = 1;
|
nkeys = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_statistic_staattnum,
|
Anum_pg_statistic_staattnum,
|
||||||
BTEqualStrategyNumber, F_INT2EQ,
|
BTEqualStrategyNumber, F_INT2EQ,
|
||||||
Int16GetDatum(attnum), INT2OID);
|
Int16GetDatum(attnum));
|
||||||
nkeys = 2;
|
nkeys = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2050,10 +2049,10 @@ heap_truncate_check_FKs(Relation rel)
|
||||||
*/
|
*/
|
||||||
fkeyRel = heap_openr(ConstraintRelationName, AccessShareLock);
|
fkeyRel = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_constraint_confrelid,
|
Anum_pg_constraint_confrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
fkeyScan = systable_beginscan(fkeyRel, NULL, false,
|
fkeyScan = systable_beginscan(fkeyRel, NULL, false,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.220 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.221 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
|
@ -992,10 +992,10 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
|
||||||
{
|
{
|
||||||
ScanKeyData key[1];
|
ScanKeyData key[1];
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
||||||
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
||||||
|
@ -1195,10 +1195,10 @@ UpdateStats(Oid relid, double reltuples)
|
||||||
{
|
{
|
||||||
ScanKeyData key[1];
|
ScanKeyData key[1];
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
||||||
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.17 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.18 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -281,15 +281,15 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con
|
||||||
|
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_constraint_conname,
|
Anum_pg_constraint_conname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(cname), NAMEOID);
|
CStringGetDatum(cname));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_constraint_connamespace,
|
Anum_pg_constraint_connamespace,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(objNamespace), OIDOID);
|
ObjectIdGetDatum(objNamespace));
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
@ -355,15 +355,15 @@ GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, i
|
||||||
*/
|
*/
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_constraint_conname,
|
Anum_pg_constraint_conname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(cname), NAMEOID);
|
CStringGetDatum(cname));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_constraint_connamespace,
|
Anum_pg_constraint_connamespace,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(objNamespace), OIDOID);
|
ObjectIdGetDatum(objNamespace));
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
@ -422,10 +422,10 @@ RemoveConstraintById(Oid conId)
|
||||||
|
|
||||||
conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(conId), OIDOID);
|
ObjectIdGetDatum(conId));
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.16 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.17 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +21,6 @@
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "catalog/pg_conversion.h"
|
#include "catalog/pg_conversion.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
@ -177,10 +176,10 @@ RemoveConversionById(Oid conversionOid)
|
||||||
HeapScanDesc scan;
|
HeapScanDesc scan;
|
||||||
ScanKeyData scanKeyData;
|
ScanKeyData scanKeyData;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scanKeyData, 0,
|
ScanKeyInit(&scanKeyData,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(conversionOid), OIDOID);
|
ObjectIdGetDatum(conversionOid));
|
||||||
|
|
||||||
/* open pg_conversion */
|
/* open pg_conversion */
|
||||||
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
|
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.8 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.9 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/pg_depend.h"
|
#include "catalog/pg_depend.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
|
||||||
|
@ -139,14 +138,14 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId)
|
||||||
|
|
||||||
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_classid,
|
Anum_pg_depend_classid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(classId), OIDOID);
|
ObjectIdGetDatum(classId));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_objid,
|
Anum_pg_depend_objid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(objectId), OIDOID);
|
ObjectIdGetDatum(objectId));
|
||||||
|
|
||||||
scan = systable_beginscan(depRel, DependDependerIndex, true,
|
scan = systable_beginscan(depRel, DependDependerIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
|
@ -181,15 +180,15 @@ isObjectPinned(const ObjectAddress *object, Relation rel)
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
ScanKeyData key[2];
|
ScanKeyData key[2];
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_refclassid,
|
Anum_pg_depend_refclassid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->classId), OIDOID);
|
ObjectIdGetDatum(object->classId));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_refobjid,
|
Anum_pg_depend_refobjid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(object->objectId), OIDOID);
|
ObjectIdGetDatum(object->objectId));
|
||||||
|
|
||||||
scan = systable_beginscan(rel, DependReferenceIndex, true,
|
scan = systable_beginscan(rel, DependReferenceIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.18 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.19 2003/11/12 21:15:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_largeobject.h"
|
#include "catalog/pg_largeobject.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
@ -82,10 +81,10 @@ LargeObjectDrop(Oid loid)
|
||||||
SysScanDesc sd;
|
SysScanDesc sd;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(loid), OIDOID);
|
ObjectIdGetDatum(loid));
|
||||||
|
|
||||||
pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
|
pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
@ -120,10 +119,10 @@ LargeObjectExists(Oid loid)
|
||||||
/*
|
/*
|
||||||
* See if we can find any tuples belonging to the specified LO
|
* See if we can find any tuples belonging to the specified LO
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(loid), OIDOID);
|
ObjectIdGetDatum(loid));
|
||||||
|
|
||||||
pg_largeobject = heap_openr(LargeObjectRelationName, AccessShareLock);
|
pg_largeobject = heap_openr(LargeObjectRelationName, AccessShareLock);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.103 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.104 2003/11/12 21:15:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,6 @@
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/pg_listener.h"
|
#include "catalog/pg_listener.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
|
@ -353,10 +352,10 @@ Async_UnlistenAll(void)
|
||||||
tdesc = RelationGetDescr(lRel);
|
tdesc = RelationGetDescr(lRel);
|
||||||
|
|
||||||
/* Find and delete all entries with my listenerPID */
|
/* Find and delete all entries with my listenerPID */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_listener_pid,
|
Anum_pg_listener_pid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(MyProcPid), INT4OID);
|
Int32GetDatum(MyProcPid));
|
||||||
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
||||||
|
|
||||||
while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||||
|
@ -817,10 +816,10 @@ ProcessIncomingNotify(void)
|
||||||
tdesc = RelationGetDescr(lRel);
|
tdesc = RelationGetDescr(lRel);
|
||||||
|
|
||||||
/* Scan only entries with my listenerPID */
|
/* Scan only entries with my listenerPID */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_listener_pid,
|
Anum_pg_listener_pid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(MyProcPid), INT4OID);
|
Int32GetDatum(MyProcPid));
|
||||||
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
||||||
|
|
||||||
/* Prepare data for rewriting 0 into notification field */
|
/* Prepare data for rewriting 0 into notification field */
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.117 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.118 2003/11/12 21:15:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -26,7 +26,6 @@
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/cluster.h"
|
#include "commands/cluster.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -879,10 +878,10 @@ get_tables_to_cluster(MemoryContext cluster_context)
|
||||||
* when called with one of them as argument.
|
* when called with one of them as argument.
|
||||||
*/
|
*/
|
||||||
indRelation = relation_openr(IndexRelationName, AccessShareLock);
|
indRelation = relation_openr(IndexRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry, 0,
|
ScanKeyInit(&entry,
|
||||||
Anum_pg_index_indisclustered,
|
Anum_pg_index_indisclustered,
|
||||||
BTEqualStrategyNumber, F_BOOLEQ,
|
BTEqualStrategyNumber, F_BOOLEQ,
|
||||||
BoolGetDatum(true), BOOLOID);
|
BoolGetDatum(true));
|
||||||
scan = heap_beginscan(indRelation, SnapshotNow, 1, &entry);
|
scan = heap_beginscan(indRelation, SnapshotNow, 1, &entry);
|
||||||
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.72 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.73 2003/11/12 21:15:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -156,18 +156,18 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
|
||||||
|
|
||||||
/* Use the index to search for a matching old tuple */
|
/* Use the index to search for a matching old tuple */
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_description_objoid,
|
Anum_pg_description_objoid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(oid), OIDOID);
|
ObjectIdGetDatum(oid));
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_description_classoid,
|
Anum_pg_description_classoid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(classoid), OIDOID);
|
ObjectIdGetDatum(classoid));
|
||||||
ScanKeyEntryInitialize(&skey[2], 0,
|
ScanKeyInit(&skey[2],
|
||||||
Anum_pg_description_objsubid,
|
Anum_pg_description_objsubid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(subid), INT4OID);
|
Int32GetDatum(subid));
|
||||||
|
|
||||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
@ -231,21 +231,21 @@ DeleteComments(Oid oid, Oid classoid, int32 subid)
|
||||||
|
|
||||||
/* Use the index to search for all matching old tuples */
|
/* Use the index to search for all matching old tuples */
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_description_objoid,
|
Anum_pg_description_objoid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(oid), OIDOID);
|
ObjectIdGetDatum(oid));
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_description_classoid,
|
Anum_pg_description_classoid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(classoid), OIDOID);
|
ObjectIdGetDatum(classoid));
|
||||||
|
|
||||||
if (subid != 0)
|
if (subid != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&skey[2], 0,
|
ScanKeyInit(&skey[2],
|
||||||
Anum_pg_description_objsubid,
|
Anum_pg_description_objsubid,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(subid), INT4OID);
|
Int32GetDatum(subid));
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -538,10 +538,10 @@ CommentRule(List *qualname, char *comment)
|
||||||
rulename = strVal(lfirst(qualname));
|
rulename = strVal(lfirst(qualname));
|
||||||
|
|
||||||
/* Search pg_rewrite for such a rule */
|
/* Search pg_rewrite for such a rule */
|
||||||
ScanKeyEntryInitialize(&scanKeyData, 0,
|
ScanKeyInit(&scanKeyData,
|
||||||
Anum_pg_rewrite_rulename,
|
Anum_pg_rewrite_rulename,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(rulename), NAMEOID);
|
PointerGetDatum(rulename));
|
||||||
|
|
||||||
RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
|
RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
|
scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
|
||||||
|
@ -791,15 +791,14 @@ CommentTrigger(List *qualname, char *comment)
|
||||||
* because of the unique index.
|
* because of the unique index.
|
||||||
*/
|
*/
|
||||||
pg_trigger = heap_openr(TriggerRelationName, AccessShareLock);
|
pg_trigger = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
ScanKeyInit(&entry[1],
|
||||||
ScanKeyEntryInitialize(&entry[1], 0,
|
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(trigname), NAMEOID);
|
CStringGetDatum(trigname));
|
||||||
scan = systable_beginscan(pg_trigger, TriggerRelidNameIndex, true,
|
scan = systable_beginscan(pg_trigger, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 2, entry);
|
SnapshotNow, 2, entry);
|
||||||
triggertuple = systable_getnext(scan);
|
triggertuple = systable_getnext(scan);
|
||||||
|
@ -872,11 +871,10 @@ CommentConstraint(List *qualname, char *comment)
|
||||||
*/
|
*/
|
||||||
pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
|
pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_constraint_conrelid,
|
Anum_pg_constraint_conrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true,
|
scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.125 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.126 2003/11/12 21:15:50 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_shadow.h"
|
#include "catalog/pg_shadow.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -531,10 +530,10 @@ dropdb(const char *dbname)
|
||||||
/*
|
/*
|
||||||
* Find the database's tuple by OID (should be unique).
|
* Find the database's tuple by OID (should be unique).
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(db_id), OIDOID);
|
ObjectIdGetDatum(db_id));
|
||||||
|
|
||||||
pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true,
|
pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
|
@ -616,10 +615,10 @@ RenameDatabase(const char *oldname, const char *newname)
|
||||||
*/
|
*/
|
||||||
rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(oldname), NAMEOID);
|
NameGetDatum(oldname));
|
||||||
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
|
|
||||||
|
@ -651,10 +650,10 @@ RenameDatabase(const char *oldname, const char *newname)
|
||||||
oldname)));
|
oldname)));
|
||||||
|
|
||||||
/* make sure the new name doesn't exist */
|
/* make sure the new name doesn't exist */
|
||||||
ScanKeyEntryInitialize(&key2, 0,
|
ScanKeyInit(&key2,
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(newname), NAMEOID);
|
NameGetDatum(newname));
|
||||||
scan2 = systable_beginscan(rel, DatabaseNameIndex, true,
|
scan2 = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
SnapshotNow, 1, &key2);
|
SnapshotNow, 1, &key2);
|
||||||
if (HeapTupleIsValid(systable_getnext(scan2)))
|
if (HeapTupleIsValid(systable_getnext(scan2)))
|
||||||
|
@ -712,10 +711,10 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||||
valuestr = flatten_set_variable_args(stmt->variable, stmt->value);
|
valuestr = flatten_set_variable_args(stmt->variable, stmt->value);
|
||||||
|
|
||||||
rel = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
rel = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
||||||
ScanKeyEntryInitialize(&scankey, 0,
|
ScanKeyInit(&scankey,
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(stmt->dbname), NAMEOID);
|
NameGetDatum(stmt->dbname));
|
||||||
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
SnapshotNow, 1, &scankey);
|
SnapshotNow, 1, &scankey);
|
||||||
tuple = systable_getnext(scan);
|
tuple = systable_getnext(scan);
|
||||||
|
@ -795,10 +794,10 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
|
||||||
/* Caller may wish to grab a better lock on pg_database beforehand... */
|
/* Caller may wish to grab a better lock on pg_database beforehand... */
|
||||||
relation = heap_openr(DatabaseRelationName, AccessShareLock);
|
relation = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scanKey, 0,
|
ScanKeyInit(&scanKey,
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(name), NAMEOID);
|
NameGetDatum(name));
|
||||||
|
|
||||||
scan = systable_beginscan(relation, DatabaseNameIndex, true,
|
scan = systable_beginscan(relation, DatabaseNameIndex, true,
|
||||||
SnapshotNow, 1, &scanKey);
|
SnapshotNow, 1, &scanKey);
|
||||||
|
@ -1001,10 +1000,10 @@ get_database_oid(const char *dbname)
|
||||||
|
|
||||||
/* There's no syscache for pg_database, so must look the hard way */
|
/* There's no syscache for pg_database, so must look the hard way */
|
||||||
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(dbname), NAMEOID);
|
CStringGetDatum(dbname));
|
||||||
scan = systable_beginscan(pg_database, DatabaseNameIndex, true,
|
scan = systable_beginscan(pg_database, DatabaseNameIndex, true,
|
||||||
SnapshotNow, 1, entry);
|
SnapshotNow, 1, entry);
|
||||||
|
|
||||||
|
@ -1041,10 +1040,10 @@ get_database_name(Oid dbid)
|
||||||
|
|
||||||
/* There's no syscache for pg_database, so must look the hard way */
|
/* There's no syscache for pg_database, so must look the hard way */
|
||||||
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(dbid), OIDOID);
|
ObjectIdGetDatum(dbid));
|
||||||
scan = systable_beginscan(pg_database, DatabaseOidIndex, true,
|
scan = systable_beginscan(pg_database, DatabaseOidIndex, true,
|
||||||
SnapshotNow, 1, entry);
|
SnapshotNow, 1, entry);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.39 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.40 2003/11/12 21:15:50 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* These routines take the parse tree and pick out the
|
* These routines take the parse tree and pick out the
|
||||||
|
@ -1097,10 +1097,10 @@ DropCastById(Oid castOid)
|
||||||
|
|
||||||
relation = heap_openr(CastRelationName, RowExclusiveLock);
|
relation = heap_openr(CastRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scankey, 0,
|
ScanKeyInit(&scankey,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(castOid), OIDOID);
|
ObjectIdGetDatum(castOid));
|
||||||
scan = systable_beginscan(relation, CastOidIndex, true,
|
scan = systable_beginscan(relation, CastOidIndex, true,
|
||||||
SnapshotNow, 1, &scankey);
|
SnapshotNow, 1, &scankey);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.114 2003/10/02 06:34:03 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.115 2003/11/12 21:15:50 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -416,6 +416,9 @@ GetIndexOpClass(List *opclass, Oid attrType,
|
||||||
* Release 7.2 renames timestamp_ops to timestamptz_ops, so suppress that
|
* Release 7.2 renames timestamp_ops to timestamptz_ops, so suppress that
|
||||||
* too for awhile. I'm starting to think we need a better approach.
|
* too for awhile. I'm starting to think we need a better approach.
|
||||||
* tgl 2000/10/01
|
* tgl 2000/10/01
|
||||||
|
*
|
||||||
|
* Release 7.5 removes bigbox_ops (which was dead code for a long while
|
||||||
|
* anyway). tgl 2003/11/11
|
||||||
*/
|
*/
|
||||||
if (length(opclass) == 1)
|
if (length(opclass) == 1)
|
||||||
{
|
{
|
||||||
|
@ -425,7 +428,8 @@ GetIndexOpClass(List *opclass, Oid attrType,
|
||||||
strcmp(claname, "timespan_ops") == 0 ||
|
strcmp(claname, "timespan_ops") == 0 ||
|
||||||
strcmp(claname, "datetime_ops") == 0 ||
|
strcmp(claname, "datetime_ops") == 0 ||
|
||||||
strcmp(claname, "lztext_ops") == 0 ||
|
strcmp(claname, "lztext_ops") == 0 ||
|
||||||
strcmp(claname, "timestamp_ops") == 0)
|
strcmp(claname, "timestamp_ops") == 0 ||
|
||||||
|
strcmp(claname, "bigbox_ops") == 0)
|
||||||
opclass = NIL;
|
opclass = NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.22 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.23 2003/11/12 21:15:50 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
#include "catalog/pg_amop.h"
|
#include "catalog/pg_amop.h"
|
||||||
#include "catalog/pg_amproc.h"
|
#include "catalog/pg_amproc.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
|
#include "catalog/pg_operator.h"
|
||||||
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -38,9 +40,24 @@
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
static void storeOperators(Oid opclassoid, int numOperators,
|
/*
|
||||||
Oid *operators, bool *recheck);
|
* We use lists of this struct type to keep track of both operators and
|
||||||
static void storeProcedures(Oid opclassoid, int numProcs, Oid *procedures);
|
* procedures during DefineOpClass.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Oid object; /* operator or support proc's OID */
|
||||||
|
int number; /* strategy or support proc number */
|
||||||
|
Oid subtype; /* subtype */
|
||||||
|
bool recheck; /* oper recheck flag (unused for proc) */
|
||||||
|
} OpClassMember;
|
||||||
|
|
||||||
|
|
||||||
|
static Oid assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid);
|
||||||
|
static Oid assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid);
|
||||||
|
static void addClassMember(List **list, OpClassMember *member, bool isProc);
|
||||||
|
static void storeOperators(Oid opclassoid, List *operators);
|
||||||
|
static void storeProcedures(Oid opclassoid, List *procedures);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -58,10 +75,9 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
opclassoid; /* oid of opclass we create */
|
opclassoid; /* oid of opclass we create */
|
||||||
int numOperators, /* amstrategies value */
|
int numOperators, /* amstrategies value */
|
||||||
numProcs; /* amsupport value */
|
numProcs; /* amsupport value */
|
||||||
Oid *operators, /* oids of operators, by strategy num */
|
List *operators; /* OpClassMember list for operators */
|
||||||
*procedures; /* oids of support procs */
|
List *procedures; /* OpClassMember list for support procs */
|
||||||
bool *recheck; /* do operators need recheck */
|
List *l;
|
||||||
List *iteml;
|
|
||||||
Relation rel;
|
Relation rel;
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
Datum values[Natts_pg_opclass];
|
Datum values[Natts_pg_opclass];
|
||||||
|
@ -123,26 +139,21 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
format_type_be(typeoid));
|
format_type_be(typeoid));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
operators = NIL;
|
||||||
|
procedures = NIL;
|
||||||
|
|
||||||
/* Storage datatype is optional */
|
/* Storage datatype is optional */
|
||||||
storageoid = InvalidOid;
|
storageoid = InvalidOid;
|
||||||
|
|
||||||
/*
|
|
||||||
* Create work arrays to hold info about operators and procedures. We
|
|
||||||
* do this mainly so that we can detect duplicate strategy numbers and
|
|
||||||
* support-proc numbers.
|
|
||||||
*/
|
|
||||||
operators = (Oid *) palloc0(sizeof(Oid) * numOperators);
|
|
||||||
procedures = (Oid *) palloc0(sizeof(Oid) * numProcs);
|
|
||||||
recheck = (bool *) palloc0(sizeof(bool) * numOperators);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan the "items" list to obtain additional info.
|
* Scan the "items" list to obtain additional info.
|
||||||
*/
|
*/
|
||||||
foreach(iteml, stmt->items)
|
foreach(l, stmt->items)
|
||||||
{
|
{
|
||||||
CreateOpClassItem *item = lfirst(iteml);
|
CreateOpClassItem *item = lfirst(l);
|
||||||
Oid operOid;
|
Oid operOid;
|
||||||
Oid funcOid;
|
Oid funcOid;
|
||||||
|
OpClassMember *member;
|
||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
Assert(IsA(item, CreateOpClassItem));
|
Assert(IsA(item, CreateOpClassItem));
|
||||||
|
@ -155,11 +166,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
errmsg("invalid operator number %d,"
|
errmsg("invalid operator number %d,"
|
||||||
" must be between 1 and %d",
|
" must be between 1 and %d",
|
||||||
item->number, numOperators)));
|
item->number, numOperators)));
|
||||||
if (operators[item->number - 1] != InvalidOid)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
||||||
errmsg("operator number %d appears more than once",
|
|
||||||
item->number)));
|
|
||||||
if (item->args != NIL)
|
if (item->args != NIL)
|
||||||
{
|
{
|
||||||
TypeName *typeName1 = (TypeName *) lfirst(item->args);
|
TypeName *typeName1 = (TypeName *) lfirst(item->args);
|
||||||
|
@ -183,8 +189,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_PROC,
|
aclcheck_error(aclresult, ACL_KIND_PROC,
|
||||||
get_func_name(funcOid));
|
get_func_name(funcOid));
|
||||||
operators[item->number - 1] = operOid;
|
/* Save the info */
|
||||||
recheck[item->number - 1] = item->recheck;
|
member = (OpClassMember *) palloc0(sizeof(OpClassMember));
|
||||||
|
member->object = operOid;
|
||||||
|
member->number = item->number;
|
||||||
|
member->subtype = assignOperSubtype(amoid, typeoid, operOid);
|
||||||
|
member->recheck = item->recheck;
|
||||||
|
addClassMember(&operators, member, false);
|
||||||
break;
|
break;
|
||||||
case OPCLASS_ITEM_FUNCTION:
|
case OPCLASS_ITEM_FUNCTION:
|
||||||
if (item->number <= 0 || item->number > numProcs)
|
if (item->number <= 0 || item->number > numProcs)
|
||||||
|
@ -193,11 +204,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
errmsg("invalid procedure number %d,"
|
errmsg("invalid procedure number %d,"
|
||||||
" must be between 1 and %d",
|
" must be between 1 and %d",
|
||||||
item->number, numProcs)));
|
item->number, numProcs)));
|
||||||
if (procedures[item->number - 1] != InvalidOid)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
||||||
errmsg("procedure number %d appears more than once",
|
|
||||||
item->number)));
|
|
||||||
funcOid = LookupFuncNameTypeNames(item->name, item->args,
|
funcOid = LookupFuncNameTypeNames(item->name, item->args,
|
||||||
false);
|
false);
|
||||||
/* Caller must have execute permission on functions */
|
/* Caller must have execute permission on functions */
|
||||||
|
@ -206,7 +212,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_PROC,
|
aclcheck_error(aclresult, ACL_KIND_PROC,
|
||||||
get_func_name(funcOid));
|
get_func_name(funcOid));
|
||||||
procedures[item->number - 1] = funcOid;
|
/* Save the info */
|
||||||
|
member = (OpClassMember *) palloc0(sizeof(OpClassMember));
|
||||||
|
member->object = funcOid;
|
||||||
|
member->number = item->number;
|
||||||
|
member->subtype = assignProcSubtype(amoid, typeoid, funcOid);
|
||||||
|
addClassMember(&procedures, member, true);
|
||||||
break;
|
break;
|
||||||
case OPCLASS_ITEM_STORAGETYPE:
|
case OPCLASS_ITEM_STORAGETYPE:
|
||||||
if (OidIsValid(storageoid))
|
if (OidIsValid(storageoid))
|
||||||
|
@ -271,10 +282,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
ScanKeyData skey[1];
|
ScanKeyData skey[1];
|
||||||
SysScanDesc scan;
|
SysScanDesc scan;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_opclass_opcamid,
|
Anum_pg_opclass_opcamid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(amoid), OIDOID);
|
ObjectIdGetDatum(amoid));
|
||||||
|
|
||||||
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -327,8 +338,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
* Now add tuples to pg_amop and pg_amproc tying in the operators and
|
* Now add tuples to pg_amop and pg_amproc tying in the operators and
|
||||||
* functions.
|
* functions.
|
||||||
*/
|
*/
|
||||||
storeOperators(opclassoid, numOperators, operators, recheck);
|
storeOperators(opclassoid, operators);
|
||||||
storeProcedures(opclassoid, numProcs, procedures);
|
storeProcedures(opclassoid, procedures);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create dependencies. Note: we do not create a dependency link to
|
* Create dependencies. Note: we do not create a dependency link to
|
||||||
|
@ -361,22 +372,22 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
|
|
||||||
/* dependencies on operators */
|
/* dependencies on operators */
|
||||||
referenced.classId = get_system_catalog_relid(OperatorRelationName);
|
referenced.classId = get_system_catalog_relid(OperatorRelationName);
|
||||||
for (i = 0; i < numOperators; i++)
|
foreach(l, operators)
|
||||||
{
|
{
|
||||||
if (operators[i] == InvalidOid)
|
OpClassMember *op = (OpClassMember *) lfirst(l);
|
||||||
continue;
|
|
||||||
referenced.objectId = operators[i];
|
referenced.objectId = op->object;
|
||||||
referenced.objectSubId = 0;
|
referenced.objectSubId = 0;
|
||||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies on procedures */
|
/* dependencies on procedures */
|
||||||
for (i = 0; i < numProcs; i++)
|
foreach(l, procedures)
|
||||||
{
|
{
|
||||||
if (procedures[i] == InvalidOid)
|
OpClassMember *proc = (OpClassMember *) lfirst(l);
|
||||||
continue;
|
|
||||||
referenced.classId = RelOid_pg_proc;
|
referenced.classId = RelOid_pg_proc;
|
||||||
referenced.objectId = procedures[i];
|
referenced.objectId = proc->object;
|
||||||
referenced.objectSubId = 0;
|
referenced.objectSubId = 0;
|
||||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
}
|
}
|
||||||
|
@ -384,26 +395,159 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the subtype to assign to an operator, and do any validity
|
||||||
|
* checking we can manage
|
||||||
|
*
|
||||||
|
* Currently this is done using hardwired rules; we don't let the user
|
||||||
|
* specify it directly.
|
||||||
|
*/
|
||||||
|
static Oid
|
||||||
|
assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid)
|
||||||
|
{
|
||||||
|
Oid subtype;
|
||||||
|
Operator optup;
|
||||||
|
Form_pg_operator opform;
|
||||||
|
|
||||||
|
/* Subtypes are currently only supported by btree, others use 0 */
|
||||||
|
if (amoid != BTREE_AM_OID)
|
||||||
|
return InvalidOid;
|
||||||
|
|
||||||
|
optup = SearchSysCache(OPEROID,
|
||||||
|
ObjectIdGetDatum(operOid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (optup == NULL)
|
||||||
|
elog(ERROR, "cache lookup failed for operator %u", operOid);
|
||||||
|
opform = (Form_pg_operator) GETSTRUCT(optup);
|
||||||
|
/*
|
||||||
|
* btree operators must be binary ops returning boolean, and the
|
||||||
|
* left-side input type must match the operator class' input type.
|
||||||
|
*/
|
||||||
|
if (opform->oprkind != 'b')
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree operators must be binary")));
|
||||||
|
if (opform->oprresult != BOOLOID)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree operators must return boolean")));
|
||||||
|
if (opform->oprleft != typeoid)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree operators must have index type as left input")));
|
||||||
|
/*
|
||||||
|
* The subtype is "default" (0) if oprright matches the operator class,
|
||||||
|
* otherwise it is oprright.
|
||||||
|
*/
|
||||||
|
if (opform->oprright == typeoid)
|
||||||
|
subtype = InvalidOid;
|
||||||
|
else
|
||||||
|
subtype = opform->oprright;
|
||||||
|
ReleaseSysCache(optup);
|
||||||
|
return subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the subtype to assign to a support procedure, and do any validity
|
||||||
|
* checking we can manage
|
||||||
|
*
|
||||||
|
* Currently this is done using hardwired rules; we don't let the user
|
||||||
|
* specify it directly.
|
||||||
|
*/
|
||||||
|
static Oid
|
||||||
|
assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid)
|
||||||
|
{
|
||||||
|
Oid subtype;
|
||||||
|
HeapTuple proctup;
|
||||||
|
Form_pg_proc procform;
|
||||||
|
|
||||||
|
/* Subtypes are currently only supported by btree, others use 0 */
|
||||||
|
if (amoid != BTREE_AM_OID)
|
||||||
|
return InvalidOid;
|
||||||
|
|
||||||
|
proctup = SearchSysCache(PROCOID,
|
||||||
|
ObjectIdGetDatum(procOid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (proctup == NULL)
|
||||||
|
elog(ERROR, "cache lookup failed for function %u", procOid);
|
||||||
|
procform = (Form_pg_proc) GETSTRUCT(proctup);
|
||||||
|
/*
|
||||||
|
* btree support procs must be 2-arg procs returning int4, and the
|
||||||
|
* first input type must match the operator class' input type.
|
||||||
|
*/
|
||||||
|
if (procform->pronargs != 2)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree procedures must have two arguments")));
|
||||||
|
if (procform->prorettype != INT4OID)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree procedures must return integer")));
|
||||||
|
if (procform->proargtypes[0] != typeoid)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("btree procedures must have index type as first input")));
|
||||||
|
/*
|
||||||
|
* The subtype is "default" (0) if second input type matches the operator
|
||||||
|
* class, otherwise it is the second input type.
|
||||||
|
*/
|
||||||
|
if (procform->proargtypes[1] == typeoid)
|
||||||
|
subtype = InvalidOid;
|
||||||
|
else
|
||||||
|
subtype = procform->proargtypes[1];
|
||||||
|
ReleaseSysCache(proctup);
|
||||||
|
return subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a new class member to the appropriate list, after checking for
|
||||||
|
* duplicated strategy or proc number.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
addClassMember(List **list, OpClassMember *member, bool isProc)
|
||||||
|
{
|
||||||
|
List *l;
|
||||||
|
|
||||||
|
foreach(l, *list)
|
||||||
|
{
|
||||||
|
OpClassMember *old = (OpClassMember *) lfirst(l);
|
||||||
|
|
||||||
|
if (old->number == member->number &&
|
||||||
|
old->subtype == member->subtype)
|
||||||
|
{
|
||||||
|
if (isProc)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("procedure number %d appears more than once",
|
||||||
|
member->number)));
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("operator number %d appears more than once",
|
||||||
|
member->number)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*list = lappend(*list, member);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump the operators to pg_amop
|
* Dump the operators to pg_amop
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
storeOperators(Oid opclassoid, int numOperators,
|
storeOperators(Oid opclassoid, List *operators)
|
||||||
Oid *operators, bool *recheck)
|
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Datum values[Natts_pg_amop];
|
Datum values[Natts_pg_amop];
|
||||||
char nulls[Natts_pg_amop];
|
char nulls[Natts_pg_amop];
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
int i,
|
List *l;
|
||||||
j;
|
int i;
|
||||||
|
|
||||||
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
for (j = 0; j < numOperators; j++)
|
foreach(l, operators)
|
||||||
{
|
{
|
||||||
if (operators[j] == InvalidOid)
|
OpClassMember *op = (OpClassMember *) lfirst(l);
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < Natts_pg_amop; ++i)
|
for (i = 0; i < Natts_pg_amop; ++i)
|
||||||
{
|
{
|
||||||
|
@ -413,9 +557,10 @@ storeOperators(Oid opclassoid, int numOperators,
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */
|
values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */
|
||||||
values[i++] = Int16GetDatum(j + 1); /* amopstrategy */
|
values[i++] = ObjectIdGetDatum(op->subtype); /* amopsubtype */
|
||||||
values[i++] = BoolGetDatum(recheck[j]); /* amopreqcheck */
|
values[i++] = Int16GetDatum(op->number); /* amopstrategy */
|
||||||
values[i++] = ObjectIdGetDatum(operators[j]); /* amopopr */
|
values[i++] = BoolGetDatum(op->recheck); /* amopreqcheck */
|
||||||
|
values[i++] = ObjectIdGetDatum(op->object); /* amopopr */
|
||||||
|
|
||||||
tup = heap_formtuple(rel->rd_att, values, nulls);
|
tup = heap_formtuple(rel->rd_att, values, nulls);
|
||||||
|
|
||||||
|
@ -433,21 +578,20 @@ storeOperators(Oid opclassoid, int numOperators,
|
||||||
* Dump the procedures (support routines) to pg_amproc
|
* Dump the procedures (support routines) to pg_amproc
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
storeProcedures(Oid opclassoid, int numProcs, Oid *procedures)
|
storeProcedures(Oid opclassoid, List *procedures)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Datum values[Natts_pg_amproc];
|
Datum values[Natts_pg_amproc];
|
||||||
char nulls[Natts_pg_amproc];
|
char nulls[Natts_pg_amproc];
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
int i,
|
List *l;
|
||||||
j;
|
int i;
|
||||||
|
|
||||||
rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
|
rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
for (j = 0; j < numProcs; j++)
|
foreach(l, procedures)
|
||||||
{
|
{
|
||||||
if (procedures[j] == InvalidOid)
|
OpClassMember *proc = (OpClassMember *) lfirst(l);
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < Natts_pg_amproc; ++i)
|
for (i = 0; i < Natts_pg_amproc; ++i)
|
||||||
{
|
{
|
||||||
|
@ -457,8 +601,9 @@ storeProcedures(Oid opclassoid, int numProcs, Oid *procedures)
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */
|
values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */
|
||||||
values[i++] = Int16GetDatum(j + 1); /* amprocnum */
|
values[i++] = ObjectIdGetDatum(proc->subtype); /* amprocsubtype */
|
||||||
values[i++] = ObjectIdGetDatum(procedures[j]); /* amproc */
|
values[i++] = Int16GetDatum(proc->number); /* amprocnum */
|
||||||
|
values[i++] = ObjectIdGetDatum(proc->object); /* amproc */
|
||||||
|
|
||||||
tup = heap_formtuple(rel->rd_att, values, nulls);
|
tup = heap_formtuple(rel->rd_att, values, nulls);
|
||||||
|
|
||||||
|
@ -590,10 +735,10 @@ RemoveOpClassById(Oid opclassOid)
|
||||||
/*
|
/*
|
||||||
* Remove associated entries in pg_amop.
|
* Remove associated entries in pg_amop.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_amop_amopclaid,
|
Anum_pg_amop_amopclaid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(opclassOid), OIDOID);
|
ObjectIdGetDatum(opclassOid));
|
||||||
|
|
||||||
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
@ -609,10 +754,10 @@ RemoveOpClassById(Oid opclassOid)
|
||||||
/*
|
/*
|
||||||
* Remove associated entries in pg_amproc.
|
* Remove associated entries in pg_amproc.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_amproc_amopclaid,
|
Anum_pg_amproc_amopclaid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(opclassOid), OIDOID);
|
ObjectIdGetDatum(opclassOid));
|
||||||
|
|
||||||
rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
|
rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.92 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.93 2003/11/12 21:15:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1393,20 +1393,20 @@ update_ri_trigger_args(Oid relid,
|
||||||
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
||||||
if (fk_scan)
|
if (fk_scan)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_trigger_tgconstrrelid,
|
Anum_pg_trigger_tgconstrrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
|
trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
|
||||||
true, SnapshotNow,
|
true, SnapshotNow,
|
||||||
1, skey);
|
1, skey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex,
|
trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex,
|
||||||
true, SnapshotNow,
|
true, SnapshotNow,
|
||||||
1, skey);
|
1, skey);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.161 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.162 2003/11/12 21:15:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -253,10 +253,10 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
||||||
* relation, so the trigger set won't be changing underneath us.
|
* relation, so the trigger set won't be changing underneath us.
|
||||||
*/
|
*/
|
||||||
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
||||||
|
@ -465,15 +465,15 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
|
||||||
*/
|
*/
|
||||||
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(trigname), NAMEOID);
|
CStringGetDatum(trigname));
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
@ -524,10 +524,10 @@ RemoveTriggerById(Oid trigOid)
|
||||||
/*
|
/*
|
||||||
* Find the trigger to delete.
|
* Find the trigger to delete.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(trigOid), OIDOID);
|
ObjectIdGetDatum(trigOid));
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -641,14 +641,14 @@ renametrig(Oid relid,
|
||||||
/*
|
/*
|
||||||
* First pass -- look for name conflict
|
* First pass -- look for name conflict
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(newname), NAMEOID);
|
PointerGetDatum(newname));
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
||||||
|
@ -661,14 +661,14 @@ renametrig(Oid relid,
|
||||||
/*
|
/*
|
||||||
* Second pass -- look for trigger existing with oldname and update
|
* Second pass -- look for trigger existing with oldname and update
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(oldname), NAMEOID);
|
PointerGetDatum(oldname));
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
||||||
|
@ -744,11 +744,10 @@ RelationBuildTriggers(Relation relation)
|
||||||
* emergency-recovery operations (ie, IsIgnoringSystemIndexes). This
|
* emergency-recovery operations (ie, IsIgnoringSystemIndexes). This
|
||||||
* in turn ensures that triggers will be fired in name order.
|
* in turn ensures that triggers will be fired in name order.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey, 0,
|
ScanKeyInit(&skey,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
|
@ -2262,10 +2261,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||||
/*
|
/*
|
||||||
* Setup to scan pg_trigger by tgconstrname ...
|
* Setup to scan pg_trigger by tgconstrname ...
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey, 0,
|
ScanKeyInit(&skey,
|
||||||
Anum_pg_trigger_tgconstrname,
|
Anum_pg_trigger_tgconstrname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(cname), NAMEOID);
|
PointerGetDatum(cname));
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerConstrNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerConstrNameIndex, true,
|
||||||
SnapshotNow, 1, &skey);
|
SnapshotNow, 1, &skey);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.49 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.50 2003/11/12 21:15:51 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
|
@ -1362,10 +1362,10 @@ AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior beha
|
||||||
conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/* Use the index to scan only constraints of the target relation */
|
/* Use the index to scan only constraints of the target relation */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_constraint_contypid,
|
Anum_pg_constraint_contypid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(HeapTupleGetOid(tup)), OIDOID);
|
ObjectIdGetDatum(HeapTupleGetOid(tup)));
|
||||||
|
|
||||||
conscan = systable_beginscan(conrel, ConstraintTypidIndex, true,
|
conscan = systable_beginscan(conrel, ConstraintTypidIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
|
@ -1615,14 +1615,14 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
|
||||||
*/
|
*/
|
||||||
depRel = relation_openr(DependRelationName, AccessShareLock);
|
depRel = relation_openr(DependRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_depend_refclassid,
|
Anum_pg_depend_refclassid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelOid_pg_type), OIDOID);
|
ObjectIdGetDatum(RelOid_pg_type));
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyInit(&key[1],
|
||||||
Anum_pg_depend_refobjid,
|
Anum_pg_depend_refobjid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(domainOid), OIDOID);
|
ObjectIdGetDatum(domainOid));
|
||||||
|
|
||||||
depScan = systable_beginscan(depRel, DependReferenceIndex, true,
|
depScan = systable_beginscan(depRel, DependReferenceIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
|
@ -1901,10 +1901,10 @@ GetDomainConstraints(Oid typeOid)
|
||||||
notNull = true;
|
notNull = true;
|
||||||
|
|
||||||
/* Look for CHECK Constraints on this domain */
|
/* Look for CHECK Constraints on this domain */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_constraint_contypid,
|
Anum_pg_constraint_contypid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(typeOid), OIDOID);
|
ObjectIdGetDatum(typeOid));
|
||||||
|
|
||||||
scan = systable_beginscan(conRel, ConstraintTypidIndex, true,
|
scan = systable_beginscan(conRel, ConstraintTypidIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.129 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.130 2003/11/12 21:15:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1074,10 +1074,10 @@ DropUser(DropUserStmt *stmt)
|
||||||
pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
|
pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
pg_dsc = RelationGetDescr(pg_rel);
|
pg_dsc = RelationGetDescr(pg_rel);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scankey, 0,
|
ScanKeyInit(&scankey,
|
||||||
Anum_pg_database_datdba,
|
Anum_pg_database_datdba,
|
||||||
BTEqualStrategyNumber, F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(usesysid), INT4OID);
|
Int32GetDatum(usesysid));
|
||||||
|
|
||||||
scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
|
scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.264 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.265 2003/11/12 21:15:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +30,6 @@
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -400,10 +399,10 @@ getrels(const RangeVar *vacrel, const char *stmttype)
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
ScanKeyData key;
|
ScanKeyData key;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_class_relkind,
|
Anum_pg_class_relkind,
|
||||||
BTEqualStrategyNumber, F_CHAREQ,
|
BTEqualStrategyNumber, F_CHAREQ,
|
||||||
CharGetDatum(RELKIND_RELATION), CHAROID);
|
CharGetDatum(RELKIND_RELATION));
|
||||||
|
|
||||||
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
||||||
|
|
||||||
|
@ -583,10 +582,10 @@ vac_update_dbstats(Oid dbid,
|
||||||
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/* Must use a heap scan, since there's no syscache for pg_database */
|
/* Must use a heap scan, since there's no syscache for pg_database */
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyInit(&entry[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(dbid), OIDOID);
|
ObjectIdGetDatum(dbid));
|
||||||
|
|
||||||
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.85 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.86 2003/11/12 21:15:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
#include "parser/parse_expr.h"
|
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -615,6 +614,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
IndexScanState *indexstate;
|
IndexScanState *indexstate;
|
||||||
List *indxqual;
|
List *indxqual;
|
||||||
List *indxstrategy;
|
List *indxstrategy;
|
||||||
|
List *indxsubtype;
|
||||||
List *indxid;
|
List *indxid;
|
||||||
int i;
|
int i;
|
||||||
int numIndices;
|
int numIndices;
|
||||||
|
@ -711,10 +711,12 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
*/
|
*/
|
||||||
indxqual = node->indxqual;
|
indxqual = node->indxqual;
|
||||||
indxstrategy = node->indxstrategy;
|
indxstrategy = node->indxstrategy;
|
||||||
|
indxsubtype = node->indxsubtype;
|
||||||
for (i = 0; i < numIndices; i++)
|
for (i = 0; i < numIndices; i++)
|
||||||
{
|
{
|
||||||
List *quals;
|
List *quals;
|
||||||
List *strategies;
|
List *strategies;
|
||||||
|
List *subtypes;
|
||||||
int n_keys;
|
int n_keys;
|
||||||
ScanKey scan_keys;
|
ScanKey scan_keys;
|
||||||
ExprState **run_keys;
|
ExprState **run_keys;
|
||||||
|
@ -724,6 +726,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
indxqual = lnext(indxqual);
|
indxqual = lnext(indxqual);
|
||||||
strategies = lfirst(indxstrategy);
|
strategies = lfirst(indxstrategy);
|
||||||
indxstrategy = lnext(indxstrategy);
|
indxstrategy = lnext(indxstrategy);
|
||||||
|
subtypes = lfirst(indxsubtype);
|
||||||
|
indxsubtype = lnext(indxsubtype);
|
||||||
n_keys = length(quals);
|
n_keys = length(quals);
|
||||||
scan_keys = (n_keys <= 0) ? (ScanKey) NULL :
|
scan_keys = (n_keys <= 0) ? (ScanKey) NULL :
|
||||||
(ScanKey) palloc(n_keys * sizeof(ScanKeyData));
|
(ScanKey) palloc(n_keys * sizeof(ScanKeyData));
|
||||||
|
@ -742,9 +746,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
AttrNumber varattno; /* att number used in scan */
|
AttrNumber varattno; /* att number used in scan */
|
||||||
StrategyNumber strategy; /* op's strategy number */
|
StrategyNumber strategy; /* op's strategy number */
|
||||||
|
Oid subtype; /* op's strategy subtype */
|
||||||
RegProcedure opfuncid; /* operator proc id used in scan */
|
RegProcedure opfuncid; /* operator proc id used in scan */
|
||||||
Datum scanvalue; /* value used in scan (if const) */
|
Datum scanvalue; /* value used in scan (if const) */
|
||||||
Oid rhstype; /* datatype of comparison value */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* extract clause information from the qualification
|
* extract clause information from the qualification
|
||||||
|
@ -753,6 +757,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
quals = lnext(quals);
|
quals = lnext(quals);
|
||||||
strategy = lfirsti(strategies);
|
strategy = lfirsti(strategies);
|
||||||
strategies = lnext(strategies);
|
strategies = lnext(strategies);
|
||||||
|
subtype = lfirsto(subtypes);
|
||||||
|
subtypes = lnext(subtypes);
|
||||||
|
|
||||||
if (!IsA(clause, OpExpr))
|
if (!IsA(clause, OpExpr))
|
||||||
elog(ERROR, "indxqual is not an OpExpr");
|
elog(ERROR, "indxqual is not an OpExpr");
|
||||||
|
@ -795,8 +801,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
*/
|
*/
|
||||||
rightop = (Expr *) get_rightop((Expr *) clause);
|
rightop = (Expr *) get_rightop((Expr *) clause);
|
||||||
|
|
||||||
rhstype = exprType((Node *) rightop);
|
|
||||||
|
|
||||||
if (rightop && IsA(rightop, RelabelType))
|
if (rightop && IsA(rightop, RelabelType))
|
||||||
rightop = ((RelabelType *) rightop)->arg;
|
rightop = ((RelabelType *) rightop)->arg;
|
||||||
|
|
||||||
|
@ -832,9 +836,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||||
varattno, /* attribute number to
|
varattno, /* attribute number to
|
||||||
* scan */
|
* scan */
|
||||||
strategy, /* op's strategy */
|
strategy, /* op's strategy */
|
||||||
|
subtype, /* strategy subtype */
|
||||||
opfuncid, /* reg proc to use */
|
opfuncid, /* reg proc to use */
|
||||||
scanvalue, /* constant */
|
scanvalue); /* constant */
|
||||||
rhstype); /* constant's type */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.266 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.267 2003/11/12 21:15:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -273,6 +273,17 @@ _copyIndexScan(IndexScan *from)
|
||||||
}
|
}
|
||||||
newnode->indxstrategy = newstrat;
|
newnode->indxstrategy = newstrat;
|
||||||
}
|
}
|
||||||
|
/* this can become COPY_NODE_FIELD when OID lists are normal objects: */
|
||||||
|
{
|
||||||
|
List *newsubtype = NIL;
|
||||||
|
List *tmp;
|
||||||
|
|
||||||
|
foreach(tmp, from->indxsubtype)
|
||||||
|
{
|
||||||
|
newsubtype = lappend(newsubtype, listCopy(lfirst(tmp)));
|
||||||
|
}
|
||||||
|
newnode->indxsubtype = newsubtype;
|
||||||
|
}
|
||||||
COPY_SCALAR_FIELD(indxorderdir);
|
COPY_SCALAR_FIELD(indxorderdir);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.219 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.220 2003/11/12 21:15:52 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
|
@ -346,6 +346,16 @@ _outIndexScan(StringInfo str, IndexScan *node)
|
||||||
_outIntList(str, lfirst(tmp));
|
_outIntList(str, lfirst(tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* this can become WRITE_NODE_FIELD when OID lists are normal objects: */
|
||||||
|
{
|
||||||
|
List *tmp;
|
||||||
|
|
||||||
|
appendStringInfo(str, " :indxsubtype ");
|
||||||
|
foreach(tmp, node->indxsubtype)
|
||||||
|
{
|
||||||
|
_outOidList(str, lfirst(tmp));
|
||||||
|
}
|
||||||
|
}
|
||||||
WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
|
WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.147 2003/08/04 02:40:00 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.148 2003/11/12 21:15:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1072,7 +1072,7 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
|
||||||
*
|
*
|
||||||
* If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
|
* If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
|
||||||
* want to determine whether "ATTR target_op CONST2" must also be true, then
|
* want to determine whether "ATTR target_op CONST2" must also be true, then
|
||||||
* you can use "CONST1 test_op CONST2" as a test. If this test returns true,
|
* you can use "CONST2 test_op CONST1" as a test. If this test returns true,
|
||||||
* then the target expression must be true; if the test returns false, then
|
* then the target expression must be true; if the test returns false, then
|
||||||
* the target expression may be false.
|
* the target expression may be false.
|
||||||
*
|
*
|
||||||
|
@ -1082,11 +1082,11 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
|
||||||
|
|
||||||
static const StrategyNumber
|
static const StrategyNumber
|
||||||
BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
|
BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
|
||||||
{2, 2, 0, 0, 0},
|
{4, 4, 0, 0, 0},
|
||||||
{1, 2, 0, 0, 0},
|
{5, 4, 0, 0, 0},
|
||||||
{1, 2, 3, 4, 5},
|
{5, 4, 3, 2, 1},
|
||||||
{0, 0, 0, 4, 5},
|
{0, 0, 0, 2, 1},
|
||||||
{0, 0, 0, 4, 4}
|
{0, 0, 0, 2, 2}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1118,12 +1118,13 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
*clause_const;
|
*clause_const;
|
||||||
Oid pred_op,
|
Oid pred_op,
|
||||||
clause_op,
|
clause_op,
|
||||||
test_op;
|
test_op = InvalidOid;
|
||||||
Oid opclass_id = InvalidOid;
|
Oid opclass_id;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
StrategyNumber pred_strategy = 0,
|
StrategyNumber pred_strategy,
|
||||||
clause_strategy = 0,
|
clause_strategy,
|
||||||
test_strategy;
|
test_strategy;
|
||||||
|
Oid clause_subtype;
|
||||||
Expr *test_expr;
|
Expr *test_expr;
|
||||||
ExprState *test_exprstate;
|
ExprState *test_exprstate;
|
||||||
Datum test_result;
|
Datum test_result;
|
||||||
|
@ -1140,7 +1141,9 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
/*
|
/*
|
||||||
* Can't do anything more unless they are both binary opclauses with a
|
* Can't do anything more unless they are both binary opclauses with a
|
||||||
* Var on the left and a Const on the right. (XXX someday try to
|
* Var on the left and a Const on the right. (XXX someday try to
|
||||||
* commute Const/Var cases?)
|
* commute Const/Var cases?) Note we don't have to think about binary
|
||||||
|
* relabeling of the Const node, since that would have been folded right
|
||||||
|
* into the Const.
|
||||||
*/
|
*/
|
||||||
if (!is_opclause(predicate))
|
if (!is_opclause(predicate))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1173,14 +1176,20 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
clause_op = ((OpExpr *) clause)->opno;
|
clause_op = ((OpExpr *) clause)->opno;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1. Find "btree" strategy numbers for the pred_op and clause_op.
|
* Try to find a btree opclass containing the needed operators.
|
||||||
*
|
*
|
||||||
* We must find a btree opclass that contains both operators, else the
|
* We must find a btree opclass that contains both operators, else the
|
||||||
* implication can't be determined. If there are multiple such
|
* implication can't be determined. Also, the pred_op has to be of
|
||||||
* opclasses, assume we can use any one to determine the logical
|
* default subtype (implying left and right input datatypes are the same);
|
||||||
* relationship of the two operators and the correct corresponding
|
* otherwise it's unsafe to put the pred_const on the left side of the
|
||||||
* test operator. This should work for any logically consistent
|
* test. Also, the opclass must contain a suitable test operator
|
||||||
* opclasses.
|
* matching the clause_const's type (which we take to mean that it has
|
||||||
|
* the same subtype as the original clause_operator).
|
||||||
|
*
|
||||||
|
* If there are multiple matching opclasses, assume we can use any one to
|
||||||
|
* determine the logical relationship of the two operators and the correct
|
||||||
|
* corresponding test operator. This should work for any logically
|
||||||
|
* consistent opclasses.
|
||||||
*/
|
*/
|
||||||
catlist = SearchSysCacheList(AMOPOPID, 1,
|
catlist = SearchSysCacheList(AMOPOPID, 1,
|
||||||
ObjectIdGetDatum(pred_op),
|
ObjectIdGetDatum(pred_op),
|
||||||
|
@ -1192,7 +1201,13 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple);
|
Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple);
|
||||||
HeapTuple clause_tuple;
|
HeapTuple clause_tuple;
|
||||||
|
|
||||||
if (!opclass_is_btree(pred_form->amopclaid))
|
opclass_id = pred_form->amopclaid;
|
||||||
|
|
||||||
|
/* must be btree */
|
||||||
|
if (!opclass_is_btree(opclass_id))
|
||||||
|
continue;
|
||||||
|
/* predicate operator must be default within this opclass */
|
||||||
|
if (pred_form->amopsubtype != InvalidOid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Get the predicate operator's btree strategy number */
|
/* Get the predicate operator's btree strategy number */
|
||||||
|
@ -1200,12 +1215,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
Assert(pred_strategy >= 1 && pred_strategy <= 5);
|
Assert(pred_strategy >= 1 && pred_strategy <= 5);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember which operator class this strategy number came from
|
* From the same opclass, find a strategy number for the clause_op,
|
||||||
*/
|
|
||||||
opclass_id = pred_form->amopclaid;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* From the same opclass, find a strategy num for the clause_op,
|
|
||||||
* if possible
|
* if possible
|
||||||
*/
|
*/
|
||||||
clause_tuple = SearchSysCache(AMOPOPID,
|
clause_tuple = SearchSysCache(AMOPOPID,
|
||||||
|
@ -1216,15 +1226,37 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
{
|
{
|
||||||
Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
|
Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
|
||||||
|
|
||||||
/* Get the restriction clause operator's strategy number */
|
/* Get the restriction clause operator's strategy/subtype */
|
||||||
clause_strategy = (StrategyNumber) clause_form->amopstrategy;
|
clause_strategy = (StrategyNumber) clause_form->amopstrategy;
|
||||||
Assert(clause_strategy >= 1 && clause_strategy <= 5);
|
Assert(clause_strategy >= 1 && clause_strategy <= 5);
|
||||||
|
clause_subtype = clause_form->amopsubtype;
|
||||||
|
|
||||||
|
/* done with clause_tuple */
|
||||||
ReleaseSysCache(clause_tuple);
|
ReleaseSysCache(clause_tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the "test" strategy number in the implication table
|
||||||
|
*/
|
||||||
|
test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
|
||||||
|
if (test_strategy == 0)
|
||||||
|
{
|
||||||
|
/* Can't determine implication using this interpretation */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if opclass has an operator for the test strategy and the
|
||||||
|
* clause datatype.
|
||||||
|
*/
|
||||||
|
test_op = get_opclass_member(opclass_id, clause_subtype,
|
||||||
|
test_strategy);
|
||||||
|
if (OidIsValid(test_op))
|
||||||
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseSysCacheList(catlist);
|
ReleaseSysCacheList(catlist);
|
||||||
|
|
||||||
|
@ -1235,25 +1267,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Look up the "test" strategy number in the implication table
|
* Evaluate the test. For this we need an EState.
|
||||||
*/
|
|
||||||
test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
|
|
||||||
if (test_strategy == 0)
|
|
||||||
return false; /* the implication cannot be determined */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 3. From the same opclass, find the operator for the test strategy
|
|
||||||
*/
|
|
||||||
test_op = get_opclass_member(opclass_id, test_strategy);
|
|
||||||
if (!OidIsValid(test_op))
|
|
||||||
{
|
|
||||||
/* This should not fail, else pg_amop entry is missing */
|
|
||||||
elog(ERROR, "missing pg_amop entry for opclass %u strategy %d",
|
|
||||||
opclass_id, test_strategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 4. Evaluate the test. For this we need an EState.
|
|
||||||
*/
|
*/
|
||||||
estate = CreateExecutorState();
|
estate = CreateExecutorState();
|
||||||
|
|
||||||
|
@ -1264,8 +1278,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||||
test_expr = make_opclause(test_op,
|
test_expr = make_opclause(test_op,
|
||||||
BOOLOID,
|
BOOLOID,
|
||||||
false,
|
false,
|
||||||
(Expr *) clause_const,
|
(Expr *) pred_const,
|
||||||
(Expr *) pred_const);
|
(Expr *) clause_const);
|
||||||
|
|
||||||
/* Prepare it for execution */
|
/* Prepare it for execution */
|
||||||
test_exprstate = ExecPrepareExpr(test_expr, estate);
|
test_exprstate = ExecPrepareExpr(test_expr, estate);
|
||||||
|
@ -1907,7 +1921,7 @@ match_special_index_operator(Expr *clause, Oid opclass,
|
||||||
* (The latter is not depended on by any part of the planner, so far as I can
|
* (The latter is not depended on by any part of the planner, so far as I can
|
||||||
* tell; but some parts of the executor do assume that the indxqual list
|
* tell; but some parts of the executor do assume that the indxqual list
|
||||||
* ultimately delivered to the executor is so ordered. One such place is
|
* ultimately delivered to the executor is so ordered. One such place is
|
||||||
* _bt_orderkeys() in the btree support. Perhaps that ought to be fixed
|
* _bt_preprocess_keys() in the btree support. Perhaps that ought to be fixed
|
||||||
* someday --- tgl 7/00)
|
* someday --- tgl 7/00)
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
|
@ -2103,7 +2117,8 @@ prefix_quals(Node *leftop, Oid opclass,
|
||||||
*/
|
*/
|
||||||
if (pstatus == Pattern_Prefix_Exact)
|
if (pstatus == Pattern_Prefix_Exact)
|
||||||
{
|
{
|
||||||
oproid = get_opclass_member(opclass, BTEqualStrategyNumber);
|
oproid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTEqualStrategyNumber);
|
||||||
if (oproid == InvalidOid)
|
if (oproid == InvalidOid)
|
||||||
elog(ERROR, "no = operator for opclass %u", opclass);
|
elog(ERROR, "no = operator for opclass %u", opclass);
|
||||||
expr = make_opclause(oproid, BOOLOID, false,
|
expr = make_opclause(oproid, BOOLOID, false,
|
||||||
|
@ -2117,7 +2132,8 @@ prefix_quals(Node *leftop, Oid opclass,
|
||||||
*
|
*
|
||||||
* We can always say "x >= prefix".
|
* We can always say "x >= prefix".
|
||||||
*/
|
*/
|
||||||
oproid = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
|
oproid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTGreaterEqualStrategyNumber);
|
||||||
if (oproid == InvalidOid)
|
if (oproid == InvalidOid)
|
||||||
elog(ERROR, "no >= operator for opclass %u", opclass);
|
elog(ERROR, "no >= operator for opclass %u", opclass);
|
||||||
expr = make_opclause(oproid, BOOLOID, false,
|
expr = make_opclause(oproid, BOOLOID, false,
|
||||||
|
@ -2132,7 +2148,8 @@ prefix_quals(Node *leftop, Oid opclass,
|
||||||
greaterstr = make_greater_string(prefix_const);
|
greaterstr = make_greater_string(prefix_const);
|
||||||
if (greaterstr)
|
if (greaterstr)
|
||||||
{
|
{
|
||||||
oproid = get_opclass_member(opclass, BTLessStrategyNumber);
|
oproid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTLessStrategyNumber);
|
||||||
if (oproid == InvalidOid)
|
if (oproid == InvalidOid)
|
||||||
elog(ERROR, "no < operator for opclass %u", opclass);
|
elog(ERROR, "no < operator for opclass %u", opclass);
|
||||||
expr = make_opclause(oproid, BOOLOID, false,
|
expr = make_opclause(oproid, BOOLOID, false,
|
||||||
|
@ -2189,13 +2206,15 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
|
||||||
*/
|
*/
|
||||||
if (is_eq)
|
if (is_eq)
|
||||||
{
|
{
|
||||||
opr1oid = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
|
opr1oid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTGreaterEqualStrategyNumber);
|
||||||
if (opr1oid == InvalidOid)
|
if (opr1oid == InvalidOid)
|
||||||
elog(ERROR, "no >= operator for opclass %u", opclass);
|
elog(ERROR, "no >= operator for opclass %u", opclass);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
opr1oid = get_opclass_member(opclass, BTGreaterStrategyNumber);
|
opr1oid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTGreaterStrategyNumber);
|
||||||
if (opr1oid == InvalidOid)
|
if (opr1oid == InvalidOid)
|
||||||
elog(ERROR, "no > operator for opclass %u", opclass);
|
elog(ERROR, "no > operator for opclass %u", opclass);
|
||||||
}
|
}
|
||||||
|
@ -2210,7 +2229,8 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
|
||||||
|
|
||||||
/* create clause "key <= network_scan_last( rightop )" */
|
/* create clause "key <= network_scan_last( rightop )" */
|
||||||
|
|
||||||
opr2oid = get_opclass_member(opclass, BTLessEqualStrategyNumber);
|
opr2oid = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTLessEqualStrategyNumber);
|
||||||
if (opr2oid == InvalidOid)
|
if (opr2oid == InvalidOid)
|
||||||
elog(ERROR, "no <= operator for opclass %u", opclass);
|
elog(ERROR, "no <= operator for opclass %u", opclass);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.158 2003/11/09 21:30:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.159 2003/11/12 21:15:53 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -63,13 +63,15 @@ static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path,
|
||||||
static void fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
static void fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
||||||
List **fixed_indexquals,
|
List **fixed_indexquals,
|
||||||
List **recheck_indexquals,
|
List **recheck_indexquals,
|
||||||
List **indxstrategy);
|
List **indxstrategy,
|
||||||
|
List **indxsubtype);
|
||||||
static void fix_indxqual_sublist(List *indexqual,
|
static void fix_indxqual_sublist(List *indexqual,
|
||||||
Relids baserelids, int baserelid,
|
Relids baserelids, int baserelid,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
List **fixed_quals,
|
List **fixed_quals,
|
||||||
List **recheck_quals,
|
List **recheck_quals,
|
||||||
List **strategy);
|
List **strategy,
|
||||||
|
List **subtype);
|
||||||
static Node *fix_indxqual_operand(Node *node, int baserelid,
|
static Node *fix_indxqual_operand(Node *node, int baserelid,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
Oid *opclass);
|
Oid *opclass);
|
||||||
|
@ -79,8 +81,8 @@ static void copy_path_costsize(Plan *dest, Path *src);
|
||||||
static void copy_plan_costsize(Plan *dest, Plan *src);
|
static void copy_plan_costsize(Plan *dest, Plan *src);
|
||||||
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
|
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
|
||||||
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
|
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
|
||||||
List *indxid, List *indxqual,
|
List *indxid, List *indxqual, List *indxqualorig,
|
||||||
List *indxqualorig, List *indxstrategy,
|
List *indxstrategy, List *indxsubtype,
|
||||||
ScanDirection indexscandir);
|
ScanDirection indexscandir);
|
||||||
static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
|
static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
|
||||||
List *tideval);
|
List *tideval);
|
||||||
|
@ -704,6 +706,7 @@ create_indexscan_plan(Query *root,
|
||||||
List *fixed_indxqual;
|
List *fixed_indxqual;
|
||||||
List *recheck_indxqual;
|
List *recheck_indxqual;
|
||||||
List *indxstrategy;
|
List *indxstrategy;
|
||||||
|
List *indxsubtype;
|
||||||
FastList indexids;
|
FastList indexids;
|
||||||
List *ixinfo;
|
List *ixinfo;
|
||||||
IndexScan *scan_plan;
|
IndexScan *scan_plan;
|
||||||
|
@ -771,7 +774,7 @@ create_indexscan_plan(Query *root,
|
||||||
*/
|
*/
|
||||||
fix_indxqual_references(indxqual, best_path,
|
fix_indxqual_references(indxqual, best_path,
|
||||||
&fixed_indxqual, &recheck_indxqual,
|
&fixed_indxqual, &recheck_indxqual,
|
||||||
&indxstrategy);
|
&indxstrategy, &indxsubtype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there were any "lossy" operators, need to add back the
|
* If there were any "lossy" operators, need to add back the
|
||||||
|
@ -804,6 +807,7 @@ create_indexscan_plan(Query *root,
|
||||||
fixed_indxqual,
|
fixed_indxqual,
|
||||||
indxqual,
|
indxqual,
|
||||||
indxstrategy,
|
indxstrategy,
|
||||||
|
indxsubtype,
|
||||||
best_path->indexscandir);
|
best_path->indexscandir);
|
||||||
|
|
||||||
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
|
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
|
||||||
|
@ -1151,8 +1155,8 @@ create_hashjoin_plan(Query *root,
|
||||||
* must add (the original form of) the indexqual clause to the "qpquals"
|
* must add (the original form of) the indexqual clause to the "qpquals"
|
||||||
* of the indexscan node, where the operator will be re-evaluated to
|
* of the indexscan node, where the operator will be re-evaluated to
|
||||||
* ensure it passes.
|
* ensure it passes.
|
||||||
* * We must construct a list of operator strategy numbers corresponding
|
* * We must construct lists of operator strategy numbers and subtypes for
|
||||||
* to the top-level operators of each index clause.
|
* the top-level operators of each index clause.
|
||||||
*
|
*
|
||||||
* Both the input list and the output lists have the form of lists of sublists
|
* Both the input list and the output lists have the form of lists of sublists
|
||||||
* of qual clauses --- the top-level list has one entry for each indexscan
|
* of qual clauses --- the top-level list has one entry for each indexscan
|
||||||
|
@ -1167,11 +1171,12 @@ create_hashjoin_plan(Query *root,
|
||||||
* need rechecking.
|
* need rechecking.
|
||||||
*
|
*
|
||||||
* indxstrategy receives a list of integer sublists of strategy numbers.
|
* indxstrategy receives a list of integer sublists of strategy numbers.
|
||||||
|
* indxsubtype receives a list of OID sublists of strategy subtypes.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
||||||
List **fixed_indexquals, List **recheck_indexquals,
|
List **fixed_indexquals, List **recheck_indexquals,
|
||||||
List **indxstrategy)
|
List **indxstrategy, List **indxsubtype)
|
||||||
{
|
{
|
||||||
FastList fixed_quals;
|
FastList fixed_quals;
|
||||||
FastList recheck_quals;
|
FastList recheck_quals;
|
||||||
|
@ -1183,6 +1188,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
||||||
FastListInit(&fixed_quals);
|
FastListInit(&fixed_quals);
|
||||||
FastListInit(&recheck_quals);
|
FastListInit(&recheck_quals);
|
||||||
*indxstrategy = NIL;
|
*indxstrategy = NIL;
|
||||||
|
*indxsubtype = NIL;
|
||||||
foreach(i, indexquals)
|
foreach(i, indexquals)
|
||||||
{
|
{
|
||||||
List *indexqual = lfirst(i);
|
List *indexqual = lfirst(i);
|
||||||
|
@ -1190,13 +1196,16 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
||||||
List *fixed_qual;
|
List *fixed_qual;
|
||||||
List *recheck_qual;
|
List *recheck_qual;
|
||||||
List *strategy;
|
List *strategy;
|
||||||
|
List *subtype;
|
||||||
|
|
||||||
fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
|
fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
|
||||||
&fixed_qual, &recheck_qual, &strategy);
|
&fixed_qual, &recheck_qual,
|
||||||
|
&strategy, &subtype);
|
||||||
FastAppend(&fixed_quals, fixed_qual);
|
FastAppend(&fixed_quals, fixed_qual);
|
||||||
if (recheck_qual != NIL)
|
if (recheck_qual != NIL)
|
||||||
FastAppend(&recheck_quals, recheck_qual);
|
FastAppend(&recheck_quals, recheck_qual);
|
||||||
*indxstrategy = lappend(*indxstrategy, strategy);
|
*indxstrategy = lappend(*indxstrategy, strategy);
|
||||||
|
*indxsubtype = lappend(*indxsubtype, subtype);
|
||||||
|
|
||||||
ixinfo = lnext(ixinfo);
|
ixinfo = lnext(ixinfo);
|
||||||
}
|
}
|
||||||
|
@ -1211,12 +1220,15 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
||||||
* For each qual clause, commute if needed to put the indexkey operand on the
|
* For each qual clause, commute if needed to put the indexkey operand on the
|
||||||
* left, and then fix its varattno. (We do not need to change the other side
|
* left, and then fix its varattno. (We do not need to change the other side
|
||||||
* of the clause.) Also change the operator if necessary, check for
|
* of the clause.) Also change the operator if necessary, check for
|
||||||
* lossy index behavior, and determine the operator's strategy number.
|
* lossy index behavior, and determine the operator's strategy number and
|
||||||
|
* subtype number.
|
||||||
*
|
*
|
||||||
* Returns three lists: the list of fixed indexquals, the list (usually
|
* Returns four lists:
|
||||||
* empty) of original clauses that must be rechecked as qpquals because
|
* the list of fixed indexquals
|
||||||
* the index is lossy for this operator type, and the integer list of
|
* the list (usually empty) of original clauses that must be rechecked
|
||||||
* strategy numbers.
|
* as qpquals because the index is lossy for this operator type
|
||||||
|
* the integer list of strategy numbers
|
||||||
|
* the OID list of strategy subtypes
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fix_indxqual_sublist(List *indexqual,
|
fix_indxqual_sublist(List *indexqual,
|
||||||
|
@ -1224,7 +1236,8 @@ fix_indxqual_sublist(List *indexqual,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
List **fixed_quals,
|
List **fixed_quals,
|
||||||
List **recheck_quals,
|
List **recheck_quals,
|
||||||
List **strategy)
|
List **strategy,
|
||||||
|
List **subtype)
|
||||||
{
|
{
|
||||||
FastList fixed_qual;
|
FastList fixed_qual;
|
||||||
FastList recheck_qual;
|
FastList recheck_qual;
|
||||||
|
@ -1233,6 +1246,7 @@ fix_indxqual_sublist(List *indexqual,
|
||||||
FastListInit(&fixed_qual);
|
FastListInit(&fixed_qual);
|
||||||
FastListInit(&recheck_qual);
|
FastListInit(&recheck_qual);
|
||||||
*strategy = NIL;
|
*strategy = NIL;
|
||||||
|
*subtype = NIL;
|
||||||
foreach(i, indexqual)
|
foreach(i, indexqual)
|
||||||
{
|
{
|
||||||
OpExpr *clause = (OpExpr *) lfirst(i);
|
OpExpr *clause = (OpExpr *) lfirst(i);
|
||||||
|
@ -1240,6 +1254,7 @@ fix_indxqual_sublist(List *indexqual,
|
||||||
Relids leftvarnos;
|
Relids leftvarnos;
|
||||||
Oid opclass;
|
Oid opclass;
|
||||||
int stratno;
|
int stratno;
|
||||||
|
Oid stratsubtype;
|
||||||
bool recheck;
|
bool recheck;
|
||||||
|
|
||||||
if (!IsA(clause, OpExpr) ||
|
if (!IsA(clause, OpExpr) ||
|
||||||
|
@ -1278,13 +1293,14 @@ fix_indxqual_sublist(List *indexqual,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the operator in the operator class to get its strategy
|
* Look up the operator in the operator class to get its strategy
|
||||||
* number and the recheck indicator. This also double-checks that
|
* numbers and the recheck indicator. This also double-checks that
|
||||||
* we found an operator matching the index.
|
* we found an operator matching the index.
|
||||||
*/
|
*/
|
||||||
get_op_opclass_properties(newclause->opno, opclass,
|
get_op_opclass_properties(newclause->opno, opclass,
|
||||||
&stratno, &recheck);
|
&stratno, &stratsubtype, &recheck);
|
||||||
|
|
||||||
*strategy = lappendi(*strategy, stratno);
|
*strategy = lappendi(*strategy, stratno);
|
||||||
|
*subtype = lappendo(*subtype, stratsubtype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If index is lossy for this operator, add (a copy of) original form
|
* If index is lossy for this operator, add (a copy of) original form
|
||||||
|
@ -1540,6 +1556,7 @@ make_indexscan(List *qptlist,
|
||||||
List *indxqual,
|
List *indxqual,
|
||||||
List *indxqualorig,
|
List *indxqualorig,
|
||||||
List *indxstrategy,
|
List *indxstrategy,
|
||||||
|
List *indxsubtype,
|
||||||
ScanDirection indexscandir)
|
ScanDirection indexscandir)
|
||||||
{
|
{
|
||||||
IndexScan *node = makeNode(IndexScan);
|
IndexScan *node = makeNode(IndexScan);
|
||||||
|
@ -1555,6 +1572,7 @@ make_indexscan(List *qptlist,
|
||||||
node->indxqual = indxqual;
|
node->indxqual = indxqual;
|
||||||
node->indxqualorig = indxqualorig;
|
node->indxqualorig = indxqualorig;
|
||||||
node->indxstrategy = indxstrategy;
|
node->indxstrategy = indxstrategy;
|
||||||
|
node->indxsubtype = indxsubtype;
|
||||||
node->indxorderdir = indexscandir;
|
node->indxorderdir = indexscandir;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.88 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.89 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,6 @@
|
||||||
#include "catalog/pg_amop.h"
|
#include "catalog/pg_amop.h"
|
||||||
#include "catalog/pg_inherits.h"
|
#include "catalog/pg_inherits.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
#include "optimizer/plancat.h"
|
#include "optimizer/plancat.h"
|
||||||
|
@ -329,10 +328,10 @@ find_inheritance_children(Oid inhparent)
|
||||||
if (!has_subclass(inhparent))
|
if (!has_subclass(inhparent))
|
||||||
return NIL;
|
return NIL;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_inherits_inhparent,
|
Anum_pg_inherits_inhparent,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(inhparent), OIDOID);
|
ObjectIdGetDatum(inhparent));
|
||||||
relation = heap_openr(InheritsRelationName, AccessShareLock);
|
relation = heap_openr(InheritsRelationName, AccessShareLock);
|
||||||
scan = heap_beginscan(relation, SnapshotNow, 1, key);
|
scan = heap_beginscan(relation, SnapshotNow, 1, key);
|
||||||
while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.162 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.163 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1039,10 +1039,10 @@ find_inheritors(Oid relid, Oid **supervec)
|
||||||
{
|
{
|
||||||
/* find all types this relid inherits from, and add them to queue */
|
/* find all types this relid inherits from, and add them to queue */
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey, 0,
|
ScanKeyInit(&skey,
|
||||||
Anum_pg_inherits_inhrelid,
|
Anum_pg_inherits_inhrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid), OIDOID);
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
|
inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.57 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.58 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "rewrite/rewriteRemove.h"
|
#include "rewrite/rewriteRemove.h"
|
||||||
#include "rewrite/rewriteSupport.h"
|
#include "rewrite/rewriteSupport.h"
|
||||||
|
@ -105,10 +104,10 @@ RemoveRewriteRuleById(Oid ruleOid)
|
||||||
/*
|
/*
|
||||||
* Find the tuple for the target rule.
|
* Find the tuple for the target rule.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(ruleOid), OIDOID);
|
ObjectIdGetDatum(ruleOid));
|
||||||
|
|
||||||
rcscan = systable_beginscan(RewriteRelation, RewriteOidIndex, true,
|
rcscan = systable_beginscan(RewriteRelation, RewriteOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.99 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.100 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -202,10 +202,10 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||||
|
|
||||||
Assert(PointerIsValid(obj_desc));
|
Assert(PointerIsValid(obj_desc));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(obj_desc->id), OIDOID);
|
ObjectIdGetDatum(obj_desc->id));
|
||||||
|
|
||||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -306,15 +306,15 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||||
if (nbytes <= 0)
|
if (nbytes <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(obj_desc->id), OIDOID);
|
ObjectIdGetDatum(obj_desc->id));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_largeobject_pageno,
|
Anum_pg_largeobject_pageno,
|
||||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
Int32GetDatum(pageno), INT4OID);
|
Int32GetDatum(pageno));
|
||||||
|
|
||||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
@ -413,15 +413,15 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||||
|
|
||||||
indstate = CatalogOpenIndexes(obj_desc->heap_r);
|
indstate = CatalogOpenIndexes(obj_desc->heap_r);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(obj_desc->id), OIDOID);
|
ObjectIdGetDatum(obj_desc->id));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyInit(&skey[1],
|
||||||
Anum_pg_largeobject_pageno,
|
Anum_pg_largeobject_pageno,
|
||||||
BTGreaterEqualStrategyNumber, F_INT4GE,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
Int32GetDatum(pageno), INT4OID);
|
Int32GetDatum(pageno));
|
||||||
|
|
||||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.94 2003/09/25 06:58:03 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.95 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -839,6 +839,26 @@ btfloat8cmp(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
|
PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btfloat48cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
float4 arg1 = PG_GETARG_FLOAT4(0);
|
||||||
|
float8 arg2 = PG_GETARG_FLOAT8(1);
|
||||||
|
|
||||||
|
/* widen float4 to float8 and then compare */
|
||||||
|
PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
btfloat84cmp(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
float8 arg1 = PG_GETARG_FLOAT8(0);
|
||||||
|
float4 arg2 = PG_GETARG_FLOAT4(1);
|
||||||
|
|
||||||
|
/* widen float4 to float8 and then compare */
|
||||||
|
PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===================
|
* ===================
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.83 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.84 2003/11/12 21:15:54 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -92,10 +92,10 @@ regprocin(PG_FUNCTION_ARGS)
|
||||||
SysScanDesc sysscan;
|
SysScanDesc sysscan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_proc_proname,
|
Anum_pg_proc_proname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(pro_name_or_oid), NAMEOID);
|
CStringGetDatum(pro_name_or_oid));
|
||||||
|
|
||||||
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
||||||
sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
|
sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
|
||||||
|
@ -442,10 +442,10 @@ regoperin(PG_FUNCTION_ARGS)
|
||||||
SysScanDesc sysscan;
|
SysScanDesc sysscan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_operator_oprname,
|
Anum_pg_operator_oprname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(opr_name_or_oid), NAMEOID);
|
CStringGetDatum(opr_name_or_oid));
|
||||||
|
|
||||||
hdesc = heap_openr(OperatorRelationName, AccessShareLock);
|
hdesc = heap_openr(OperatorRelationName, AccessShareLock);
|
||||||
sysscan = systable_beginscan(hdesc, OperatorNameNspIndex, true,
|
sysscan = systable_beginscan(hdesc, OperatorNameNspIndex, true,
|
||||||
|
@ -820,10 +820,10 @@ regclassin(PG_FUNCTION_ARGS)
|
||||||
SysScanDesc sysscan;
|
SysScanDesc sysscan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(class_name_or_oid), NAMEOID);
|
CStringGetDatum(class_name_or_oid));
|
||||||
|
|
||||||
hdesc = heap_openr(RelationRelationName, AccessShareLock);
|
hdesc = heap_openr(RelationRelationName, AccessShareLock);
|
||||||
sysscan = systable_beginscan(hdesc, ClassNameNspIndex, true,
|
sysscan = systable_beginscan(hdesc, ClassNameNspIndex, true,
|
||||||
|
@ -986,10 +986,10 @@ regtypein(PG_FUNCTION_ARGS)
|
||||||
SysScanDesc sysscan;
|
SysScanDesc sysscan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_type_typname,
|
Anum_pg_type_typname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(typ_name_or_oid), NAMEOID);
|
CStringGetDatum(typ_name_or_oid));
|
||||||
|
|
||||||
hdesc = heap_openr(TypeRelationName, AccessShareLock);
|
hdesc = heap_openr(TypeRelationName, AccessShareLock);
|
||||||
sysscan = systable_beginscan(hdesc, TypeNameNspIndex, true,
|
sysscan = systable_beginscan(hdesc, TypeNameNspIndex, true,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.158 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.159 2003/11/12 21:15:55 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
|
@ -488,10 +488,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
|
||||||
*/
|
*/
|
||||||
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(trigid), OIDOID);
|
ObjectIdGetDatum(trigid));
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
@ -886,10 +886,10 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags)
|
||||||
*/
|
*/
|
||||||
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(constraintId), OIDOID);
|
ObjectIdGetDatum(constraintId));
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.147 2003/10/16 21:37:54 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.148 2003/11/12 21:15:55 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -952,7 +952,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
||||||
/*
|
/*
|
||||||
* Pattern specifies an exact match, so pretend operator is '='
|
* Pattern specifies an exact match, so pretend operator is '='
|
||||||
*/
|
*/
|
||||||
Oid eqopr = get_opclass_member(opclass, BTEqualStrategyNumber);
|
Oid eqopr = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTEqualStrategyNumber);
|
||||||
List *eqargs;
|
List *eqargs;
|
||||||
|
|
||||||
if (eqopr == InvalidOid)
|
if (eqopr == InvalidOid)
|
||||||
|
@ -3382,7 +3383,8 @@ prefix_selectivity(Query *root, Var *var, Oid opclass, Const *prefixcon)
|
||||||
List *cmpargs;
|
List *cmpargs;
|
||||||
Const *greaterstrcon;
|
Const *greaterstrcon;
|
||||||
|
|
||||||
cmpopr = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
|
cmpopr = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTGreaterEqualStrategyNumber);
|
||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no >= operator for opclass %u", opclass);
|
elog(ERROR, "no >= operator for opclass %u", opclass);
|
||||||
cmpargs = makeList2(var, prefixcon);
|
cmpargs = makeList2(var, prefixcon);
|
||||||
|
@ -3403,7 +3405,8 @@ prefix_selectivity(Query *root, Var *var, Oid opclass, Const *prefixcon)
|
||||||
{
|
{
|
||||||
Selectivity topsel;
|
Selectivity topsel;
|
||||||
|
|
||||||
cmpopr = get_opclass_member(opclass, BTLessStrategyNumber);
|
cmpopr = get_opclass_member(opclass, InvalidOid,
|
||||||
|
BTLessStrategyNumber);
|
||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no < operator for opclass %u", opclass);
|
elog(ERROR, "no < operator for opclass %u", opclass);
|
||||||
cmpargs = makeList2(var, greaterstrcon);
|
cmpargs = makeList2(var, greaterstrcon);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -967,9 +967,9 @@ CatalogCacheInitializeCache(CatCache *cache)
|
||||||
/* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
|
/* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
|
||||||
cache->cc_skey[i].sk_attno = cache->cc_key[i];
|
cache->cc_skey[i].sk_attno = cache->cc_key[i];
|
||||||
|
|
||||||
/* Fill in sk_strategy and sk_argtype correctly as well */
|
/* Fill in sk_strategy as well --- always standard equality */
|
||||||
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
|
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
|
||||||
cache->cc_skey[i].sk_argtype = keytype;
|
cache->cc_skey[i].sk_subtype = InvalidOid;
|
||||||
|
|
||||||
CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p",
|
CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p",
|
||||||
cache->cc_relname,
|
cache->cc_relname,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
|
@ -55,7 +55,7 @@ op_in_opclass(Oid opno, Oid opclass)
|
||||||
/*
|
/*
|
||||||
* get_op_opclass_properties
|
* get_op_opclass_properties
|
||||||
*
|
*
|
||||||
* Get the operator's strategy number and recheck (lossy) flag
|
* Get the operator's strategy number, subtype, and recheck (lossy) flag
|
||||||
* within the specified opclass.
|
* within the specified opclass.
|
||||||
*
|
*
|
||||||
* Caller should already have verified that opno is a member of opclass,
|
* Caller should already have verified that opno is a member of opclass,
|
||||||
|
@ -63,7 +63,7 @@ op_in_opclass(Oid opno, Oid opclass)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
get_op_opclass_properties(Oid opno, Oid opclass,
|
get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
int *strategy, bool *recheck)
|
int *strategy, Oid *subtype, bool *recheck)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_amop amop_tup;
|
Form_pg_amop amop_tup;
|
||||||
|
@ -77,6 +77,7 @@ get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
opno, opclass);
|
opno, opclass);
|
||||||
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
||||||
*strategy = amop_tup->amopstrategy;
|
*strategy = amop_tup->amopstrategy;
|
||||||
|
*subtype = amop_tup->amopsubtype;
|
||||||
*recheck = amop_tup->amopreqcheck;
|
*recheck = amop_tup->amopreqcheck;
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
}
|
}
|
||||||
|
@ -84,12 +85,12 @@ get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
/*
|
/*
|
||||||
* get_opclass_member
|
* get_opclass_member
|
||||||
* Get the OID of the operator that implements the specified strategy
|
* Get the OID of the operator that implements the specified strategy
|
||||||
* for the specified opclass.
|
* with the specified subtype for the specified opclass.
|
||||||
*
|
*
|
||||||
* Returns InvalidOid if there is no pg_amop entry for the given keys.
|
* Returns InvalidOid if there is no pg_amop entry for the given keys.
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
get_opclass_member(Oid opclass, int16 strategy)
|
get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_amop amop_tup;
|
Form_pg_amop amop_tup;
|
||||||
|
@ -97,8 +98,9 @@ get_opclass_member(Oid opclass, int16 strategy)
|
||||||
|
|
||||||
tp = SearchSysCache(AMOPSTRATEGY,
|
tp = SearchSysCache(AMOPSTRATEGY,
|
||||||
ObjectIdGetDatum(opclass),
|
ObjectIdGetDatum(opclass),
|
||||||
|
ObjectIdGetDatum(subtype),
|
||||||
Int16GetDatum(strategy),
|
Int16GetDatum(strategy),
|
||||||
0, 0);
|
0);
|
||||||
if (!HeapTupleIsValid(tp))
|
if (!HeapTupleIsValid(tp))
|
||||||
return InvalidOid;
|
return InvalidOid;
|
||||||
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
||||||
|
@ -149,8 +151,8 @@ get_op_hash_function(Oid opno)
|
||||||
|
|
||||||
if (OidIsValid(opclass))
|
if (OidIsValid(opclass))
|
||||||
{
|
{
|
||||||
/* Found a suitable opclass, get its hash support function */
|
/* Found a suitable opclass, get its default hash support function */
|
||||||
return get_opclass_proc(opclass, HASHPROC);
|
return get_opclass_proc(opclass, InvalidOid, HASHPROC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Didn't find a match... */
|
/* Didn't find a match... */
|
||||||
|
@ -163,12 +165,12 @@ get_op_hash_function(Oid opno)
|
||||||
/*
|
/*
|
||||||
* get_opclass_proc
|
* get_opclass_proc
|
||||||
* Get the OID of the specified support function
|
* Get the OID of the specified support function
|
||||||
* for the specified opclass.
|
* for the specified opclass and subtype.
|
||||||
*
|
*
|
||||||
* Returns InvalidOid if there is no pg_amproc entry for the given keys.
|
* Returns InvalidOid if there is no pg_amproc entry for the given keys.
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
get_opclass_proc(Oid opclass, int16 procnum)
|
get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_amproc amproc_tup;
|
Form_pg_amproc amproc_tup;
|
||||||
|
@ -176,8 +178,9 @@ get_opclass_proc(Oid opclass, int16 procnum)
|
||||||
|
|
||||||
tp = SearchSysCache(AMPROCNUM,
|
tp = SearchSysCache(AMPROCNUM,
|
||||||
ObjectIdGetDatum(opclass),
|
ObjectIdGetDatum(opclass),
|
||||||
|
ObjectIdGetDatum(subtype),
|
||||||
Int16GetDatum(procnum),
|
Int16GetDatum(procnum),
|
||||||
0, 0);
|
0);
|
||||||
if (!HeapTupleIsValid(tp))
|
if (!HeapTupleIsValid(tp))
|
||||||
return InvalidOid;
|
return InvalidOid;
|
||||||
amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
|
amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.192 2003/11/12 21:15:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -262,7 +262,7 @@ do { \
|
||||||
/*
|
/*
|
||||||
* Special cache for opclass-related information
|
* Special cache for opclass-related information
|
||||||
*
|
*
|
||||||
* Note: only non-cross-type operators and support procs get cached
|
* Note: only default-subtype operators and support procs get cached
|
||||||
*/
|
*/
|
||||||
typedef struct opclasscacheent
|
typedef struct opclasscacheent
|
||||||
{
|
{
|
||||||
|
@ -336,26 +336,23 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
|
||||||
switch (buildinfo.infotype)
|
switch (buildinfo.infotype)
|
||||||
{
|
{
|
||||||
case INFO_RELID:
|
case INFO_RELID:
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(buildinfo.i.info_id),
|
ObjectIdGetDatum(buildinfo.i.info_id));
|
||||||
OIDOID);
|
|
||||||
nkeys = 1;
|
nkeys = 1;
|
||||||
indexRelname = ClassOidIndex;
|
indexRelname = ClassOidIndex;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFO_RELNAME:
|
case INFO_RELNAME:
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyInit(&key[0],
|
||||||
Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(buildinfo.i.info_name),
|
NameGetDatum(buildinfo.i.info_name));
|
||||||
NAMEOID);
|
ScanKeyInit(&key[1],
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
|
||||||
Anum_pg_class_relnamespace,
|
Anum_pg_class_relnamespace,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
|
ObjectIdGetDatum(PG_CATALOG_NAMESPACE));
|
||||||
OIDOID);
|
|
||||||
nkeys = 2;
|
nkeys = 2;
|
||||||
indexRelname = ClassNameNspIndex;
|
indexRelname = ClassNameNspIndex;
|
||||||
break;
|
break;
|
||||||
|
@ -483,15 +480,14 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
||||||
* (Eliminating system attribute rows at the index level is lots
|
* (Eliminating system attribute rows at the index level is lots
|
||||||
* faster than fetching them.)
|
* faster than fetching them.)
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_attribute_attrelid,
|
Anum_pg_attribute_attrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
ScanKeyInit(&skey[1],
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
|
||||||
Anum_pg_attribute_attnum,
|
Anum_pg_attribute_attnum,
|
||||||
BTGreaterStrategyNumber, F_INT2GT,
|
BTGreaterStrategyNumber, F_INT2GT,
|
||||||
Int16GetDatum(0), INT2OID);
|
Int16GetDatum(0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open pg_attribute and begin a scan. Force heap scan if we haven't
|
* Open pg_attribute and begin a scan. Force heap scan if we haven't
|
||||||
|
@ -673,11 +669,10 @@ RelationBuildRuleLock(Relation relation)
|
||||||
/*
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_rewrite_ev_class,
|
Anum_pg_rewrite_ev_class,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open pg_rewrite and begin a scan
|
* open pg_rewrite and begin a scan
|
||||||
|
@ -1058,7 +1053,7 @@ RelationInitIndexAccessInfo(Relation relation)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IndexSupportInitialize
|
* IndexSupportInitialize
|
||||||
* Initializes an index's cached lists of operators and support procs,
|
* Initializes an index's cached opclass information,
|
||||||
* given the index's pg_index tuple.
|
* given the index's pg_index tuple.
|
||||||
*
|
*
|
||||||
* Data is returned into *indexOperator and *indexSupport, which are arrays
|
* Data is returned into *indexOperator and *indexSupport, which are arrays
|
||||||
|
@ -1131,11 +1126,9 @@ LookupOpclassInfo(Oid operatorClassOid,
|
||||||
{
|
{
|
||||||
OpClassCacheEnt *opcentry;
|
OpClassCacheEnt *opcentry;
|
||||||
bool found;
|
bool found;
|
||||||
Relation pg_amop_desc;
|
Relation rel;
|
||||||
Relation pg_amproc_desc;
|
SysScanDesc scan;
|
||||||
SysScanDesc pg_amop_scan;
|
ScanKeyData skey[2];
|
||||||
SysScanDesc pg_amproc_scan;
|
|
||||||
ScanKeyData key;
|
|
||||||
HeapTuple htup;
|
HeapTuple htup;
|
||||||
bool indexOK;
|
bool indexOK;
|
||||||
|
|
||||||
|
@ -1191,7 +1184,7 @@ LookupOpclassInfo(Oid operatorClassOid,
|
||||||
opcentry->supportProcs = NULL;
|
opcentry->supportProcs = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To avoid infinite recursion during startup, force a heap scan if
|
* To avoid infinite recursion during startup, force heap scans if
|
||||||
* we're looking up info for the opclasses used by the indexes we
|
* we're looking up info for the opclasses used by the indexes we
|
||||||
* would like to reference here.
|
* would like to reference here.
|
||||||
*/
|
*/
|
||||||
|
@ -1200,24 +1193,25 @@ LookupOpclassInfo(Oid operatorClassOid,
|
||||||
operatorClassOid != INT2_BTREE_OPS_OID);
|
operatorClassOid != INT2_BTREE_OPS_OID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan pg_amop to obtain operators for the opclass
|
* Scan pg_amop to obtain operators for the opclass. We only fetch
|
||||||
|
* the default ones (those with subtype zero).
|
||||||
*/
|
*/
|
||||||
if (numStrats > 0)
|
if (numStrats > 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_amop_amopclaid,
|
Anum_pg_amop_amopclaid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(operatorClassOid),
|
ObjectIdGetDatum(operatorClassOid));
|
||||||
OIDOID);
|
ScanKeyInit(&skey[1],
|
||||||
pg_amop_desc = heap_openr(AccessMethodOperatorRelationName,
|
Anum_pg_amop_amopsubtype,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(InvalidOid));
|
||||||
|
rel = heap_openr(AccessMethodOperatorRelationName,
|
||||||
AccessShareLock);
|
AccessShareLock);
|
||||||
pg_amop_scan = systable_beginscan(pg_amop_desc,
|
scan = systable_beginscan(rel, AccessMethodStrategyIndex, indexOK,
|
||||||
AccessMethodStrategyIndex,
|
SnapshotNow, 2, skey);
|
||||||
indexOK,
|
|
||||||
SnapshotNow,
|
|
||||||
1, &key);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(htup = systable_getnext(pg_amop_scan)))
|
while (HeapTupleIsValid(htup = systable_getnext(scan)))
|
||||||
{
|
{
|
||||||
Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
|
Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
|
||||||
|
|
||||||
|
@ -1229,29 +1223,30 @@ LookupOpclassInfo(Oid operatorClassOid,
|
||||||
amopform->amopopr;
|
amopform->amopopr;
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(pg_amop_scan);
|
systable_endscan(scan);
|
||||||
heap_close(pg_amop_desc, AccessShareLock);
|
heap_close(rel, AccessShareLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan pg_amproc to obtain support procs for the opclass
|
* Scan pg_amproc to obtain support procs for the opclass. We only fetch
|
||||||
|
* the default ones (those with subtype zero).
|
||||||
*/
|
*/
|
||||||
if (numSupport > 0)
|
if (numSupport > 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_amproc_amopclaid,
|
Anum_pg_amproc_amopclaid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(operatorClassOid),
|
ObjectIdGetDatum(operatorClassOid));
|
||||||
OIDOID);
|
ScanKeyInit(&skey[1],
|
||||||
pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName,
|
Anum_pg_amproc_amprocsubtype,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(InvalidOid));
|
||||||
|
rel = heap_openr(AccessMethodProcedureRelationName,
|
||||||
AccessShareLock);
|
AccessShareLock);
|
||||||
pg_amproc_scan = systable_beginscan(pg_amproc_desc,
|
scan = systable_beginscan(rel, AccessMethodProcedureIndex, indexOK,
|
||||||
AccessMethodProcedureIndex,
|
SnapshotNow, 2, skey);
|
||||||
indexOK,
|
|
||||||
SnapshotNow,
|
|
||||||
1, &key);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(htup = systable_getnext(pg_amproc_scan)))
|
while (HeapTupleIsValid(htup = systable_getnext(scan)))
|
||||||
{
|
{
|
||||||
Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
|
Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
|
||||||
|
|
||||||
|
@ -1264,8 +1259,8 @@ LookupOpclassInfo(Oid operatorClassOid,
|
||||||
amprocform->amproc;
|
amprocform->amproc;
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(pg_amproc_scan);
|
systable_endscan(scan);
|
||||||
heap_close(pg_amproc_desc, AccessShareLock);
|
heap_close(rel, AccessShareLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
opcentry->valid = true;
|
opcentry->valid = true;
|
||||||
|
@ -2483,16 +2478,14 @@ AttrDefaultFetch(Relation relation)
|
||||||
int found;
|
int found;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey, 0,
|
ScanKeyInit(&skey,
|
||||||
Anum_pg_attrdef_adrelid,
|
Anum_pg_attrdef_adrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
||||||
adscan = systable_beginscan(adrel, AttrDefaultIndex, true,
|
adscan = systable_beginscan(adrel, AttrDefaultIndex, true,
|
||||||
SnapshotNow,
|
SnapshotNow, 1, &skey);
|
||||||
1, &skey);
|
|
||||||
found = 0;
|
found = 0;
|
||||||
|
|
||||||
while (HeapTupleIsValid(htup = systable_getnext(adscan)))
|
while (HeapTupleIsValid(htup = systable_getnext(adscan)))
|
||||||
|
@ -2550,11 +2543,10 @@ CheckConstraintFetch(Relation relation)
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_constraint_conrelid,
|
Anum_pg_constraint_conrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
conrel = heap_openr(ConstraintRelationName, AccessShareLock);
|
conrel = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
||||||
|
@ -2642,16 +2634,14 @@ RelationGetIndexList(Relation relation)
|
||||||
result = NIL;
|
result = NIL;
|
||||||
|
|
||||||
/* Prepare to scan pg_index for entries having indrelid = this rel. */
|
/* Prepare to scan pg_index for entries having indrelid = this rel. */
|
||||||
ScanKeyEntryInitialize(&skey, 0,
|
ScanKeyInit(&skey,
|
||||||
Anum_pg_index_indrelid,
|
Anum_pg_index_indrelid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)),
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
OIDOID);
|
|
||||||
|
|
||||||
indrel = heap_openr(IndexRelationName, AccessShareLock);
|
indrel = heap_openr(IndexRelationName, AccessShareLock);
|
||||||
indscan = systable_beginscan(indrel, IndexIndrelidIndex, true,
|
indscan = systable_beginscan(indrel, IndexIndrelidIndex, true,
|
||||||
SnapshotNow,
|
SnapshotNow, 1, &skey);
|
||||||
1, &skey);
|
|
||||||
|
|
||||||
while (HeapTupleIsValid(htup = systable_getnext(indscan)))
|
while (HeapTupleIsValid(htup = systable_getnext(indscan)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.91 2003/09/24 18:54:01 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.92 2003/11/12 21:15:56 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
|
@ -136,21 +136,21 @@ static const struct cachedesc cacheinfo[] = {
|
||||||
{AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
|
{AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
|
||||||
AccessMethodStrategyIndex,
|
AccessMethodStrategyIndex,
|
||||||
0,
|
0,
|
||||||
2,
|
3,
|
||||||
{
|
{
|
||||||
Anum_pg_amop_amopclaid,
|
Anum_pg_amop_amopclaid,
|
||||||
|
Anum_pg_amop_amopsubtype,
|
||||||
Anum_pg_amop_amopstrategy,
|
Anum_pg_amop_amopstrategy,
|
||||||
0,
|
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
{AccessMethodProcedureRelationName, /* AMPROCNUM */
|
{AccessMethodProcedureRelationName, /* AMPROCNUM */
|
||||||
AccessMethodProcedureIndex,
|
AccessMethodProcedureIndex,
|
||||||
0,
|
0,
|
||||||
2,
|
3,
|
||||||
{
|
{
|
||||||
Anum_pg_amproc_amopclaid,
|
Anum_pg_amproc_amopclaid,
|
||||||
|
Anum_pg_amproc_amprocsubtype,
|
||||||
Anum_pg_amproc_amprocnum,
|
Anum_pg_amproc_amprocnum,
|
||||||
0,
|
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
{AttributeRelationName, /* ATTNAME */
|
{AttributeRelationName, /* ATTNAME */
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.2 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.3 2003/11/12 21:15:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -158,22 +158,26 @@ lookup_type_cache(Oid type_id, int flags)
|
||||||
{
|
{
|
||||||
if (typentry->btree_opc != InvalidOid)
|
if (typentry->btree_opc != InvalidOid)
|
||||||
typentry->eq_opr = get_opclass_member(typentry->btree_opc,
|
typentry->eq_opr = get_opclass_member(typentry->btree_opc,
|
||||||
|
InvalidOid,
|
||||||
BTEqualStrategyNumber);
|
BTEqualStrategyNumber);
|
||||||
if (typentry->eq_opr == InvalidOid &&
|
if (typentry->eq_opr == InvalidOid &&
|
||||||
typentry->hash_opc != InvalidOid)
|
typentry->hash_opc != InvalidOid)
|
||||||
typentry->eq_opr = get_opclass_member(typentry->hash_opc,
|
typentry->eq_opr = get_opclass_member(typentry->hash_opc,
|
||||||
|
InvalidOid,
|
||||||
HTEqualStrategyNumber);
|
HTEqualStrategyNumber);
|
||||||
}
|
}
|
||||||
if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid)
|
if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid)
|
||||||
{
|
{
|
||||||
if (typentry->btree_opc != InvalidOid)
|
if (typentry->btree_opc != InvalidOid)
|
||||||
typentry->lt_opr = get_opclass_member(typentry->btree_opc,
|
typentry->lt_opr = get_opclass_member(typentry->btree_opc,
|
||||||
|
InvalidOid,
|
||||||
BTLessStrategyNumber);
|
BTLessStrategyNumber);
|
||||||
}
|
}
|
||||||
if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid)
|
if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid)
|
||||||
{
|
{
|
||||||
if (typentry->btree_opc != InvalidOid)
|
if (typentry->btree_opc != InvalidOid)
|
||||||
typentry->gt_opr = get_opclass_member(typentry->btree_opc,
|
typentry->gt_opr = get_opclass_member(typentry->btree_opc,
|
||||||
|
InvalidOid,
|
||||||
BTGreaterStrategyNumber);
|
BTGreaterStrategyNumber);
|
||||||
}
|
}
|
||||||
if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) &&
|
if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) &&
|
||||||
|
@ -181,6 +185,7 @@ lookup_type_cache(Oid type_id, int flags)
|
||||||
{
|
{
|
||||||
if (typentry->btree_opc != InvalidOid)
|
if (typentry->btree_opc != InvalidOid)
|
||||||
typentry->cmp_proc = get_opclass_proc(typentry->btree_opc,
|
typentry->cmp_proc = get_opclass_proc(typentry->btree_opc,
|
||||||
|
InvalidOid,
|
||||||
BTORDER_PROC);
|
BTORDER_PROC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,10 +253,10 @@ lookup_default_opclass(Oid type_id, Oid am_id)
|
||||||
*/
|
*/
|
||||||
rel = heap_openr(OperatorClassRelationName, AccessShareLock);
|
rel = heap_openr(OperatorClassRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyInit(&skey[0],
|
||||||
Anum_pg_opclass_opcamid,
|
Anum_pg_opclass_opcamid,
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(am_id), OIDOID);
|
ObjectIdGetDatum(am_id));
|
||||||
|
|
||||||
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.128 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.129 2003/11/12 21:15:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
|
@ -26,7 +26,6 @@
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_shadow.h"
|
#include "catalog/pg_shadow.h"
|
||||||
#include "catalog/pg_type.h"
|
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "mb/pg_wchar.h"
|
#include "mb/pg_wchar.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -92,10 +91,10 @@ ReverifyMyDatabase(const char *name)
|
||||||
*/
|
*/
|
||||||
pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
|
pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyInit(&key,
|
||||||
Anum_pg_database_datname,
|
Anum_pg_database_datname,
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(name), NAMEOID);
|
NameGetDatum(name));
|
||||||
|
|
||||||
pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
|
pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.38 2003/11/09 21:30:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.39 2003/11/12 21:15:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -472,15 +472,14 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
||||||
&state->sortFnKinds[i]);
|
&state->sortFnKinds[i]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We needn't fill in sk_strategy or sk_argtype since these scankeys
|
* We needn't fill in sk_strategy or sk_subtype since these scankeys
|
||||||
* will never be passed to an index.
|
* will never be passed to an index.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&state->scanKeys[i], 0,
|
ScanKeyInit(&state->scanKeys[i],
|
||||||
attNums[i],
|
attNums[i],
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
sortFunction,
|
sortFunction,
|
||||||
(Datum) 0,
|
(Datum) 0);
|
||||||
InvalidOid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -1739,6 +1738,10 @@ SelectSortFunction(Oid sortOperator,
|
||||||
|
|
||||||
if (!opclass_is_btree(aform->amopclaid))
|
if (!opclass_is_btree(aform->amopclaid))
|
||||||
continue;
|
continue;
|
||||||
|
/* must be of default subtype, too */
|
||||||
|
if (aform->amopsubtype != InvalidOid)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (aform->amopstrategy == BTLessStrategyNumber)
|
if (aform->amopstrategy == BTLessStrategyNumber)
|
||||||
{
|
{
|
||||||
opclass = aform->amopclaid;
|
opclass = aform->amopclaid;
|
||||||
|
@ -1757,8 +1760,8 @@ SelectSortFunction(Oid sortOperator,
|
||||||
|
|
||||||
if (OidIsValid(opclass))
|
if (OidIsValid(opclass))
|
||||||
{
|
{
|
||||||
/* Found a suitable opclass, get its comparator support function */
|
/* Found a suitable opclass, get its default comparator function */
|
||||||
*sortFunction = get_opclass_proc(opclass, BTORDER_PROC);
|
*sortFunction = get_opclass_proc(opclass, InvalidOid, BTORDER_PROC);
|
||||||
Assert(RegProcedureIsValid(*sortFunction));
|
Assert(RegProcedureIsValid(*sortFunction));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: nbtree.h,v 1.72 2003/11/09 21:30:37 tgl Exp $
|
* $Id: nbtree.h,v 1.73 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -341,7 +341,7 @@ typedef struct xl_btree_newpage
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operator strategy numbers for B-tree have been moved to access/skey.h,
|
* Operator strategy numbers for B-tree have been moved to access/skey.h,
|
||||||
* because many places need to use them in ScanKeyEntryInitialize() calls.
|
* because many places need to use them in ScanKeyInit() calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -404,12 +404,12 @@ typedef struct BTScanOpaqueData
|
||||||
Buffer btso_mrkbuf;
|
Buffer btso_mrkbuf;
|
||||||
ItemPointerData curHeapIptr;
|
ItemPointerData curHeapIptr;
|
||||||
ItemPointerData mrkHeapIptr;
|
ItemPointerData mrkHeapIptr;
|
||||||
/* these fields are set by _bt_orderkeys(), which see for more info: */
|
/* these fields are set by _bt_preprocess_keys(): */
|
||||||
bool qual_ok; /* false if qual can never be satisfied */
|
bool qual_ok; /* false if qual can never be satisfied */
|
||||||
int numberOfKeys; /* number of scan keys */
|
int numberOfKeys; /* number of preprocessed scan keys */
|
||||||
int numberOfRequiredKeys; /* number of keys that must be
|
int numberOfRequiredKeys; /* number of keys that must be
|
||||||
* matched to continue the scan */
|
* matched to continue the scan */
|
||||||
ScanKey keyData; /* array of scan keys */
|
ScanKey keyData; /* array of preprocessed scan keys */
|
||||||
} BTScanOpaqueData;
|
} BTScanOpaqueData;
|
||||||
|
|
||||||
typedef BTScanOpaqueData *BTScanOpaque;
|
typedef BTScanOpaqueData *BTScanOpaque;
|
||||||
|
@ -424,7 +424,6 @@ extern Datum btinsert(PG_FUNCTION_ARGS);
|
||||||
extern Datum btgettuple(PG_FUNCTION_ARGS);
|
extern Datum btgettuple(PG_FUNCTION_ARGS);
|
||||||
extern Datum btbeginscan(PG_FUNCTION_ARGS);
|
extern Datum btbeginscan(PG_FUNCTION_ARGS);
|
||||||
extern Datum btrescan(PG_FUNCTION_ARGS);
|
extern Datum btrescan(PG_FUNCTION_ARGS);
|
||||||
extern void btmovescan(IndexScanDesc scan, Datum v);
|
|
||||||
extern Datum btendscan(PG_FUNCTION_ARGS);
|
extern Datum btendscan(PG_FUNCTION_ARGS);
|
||||||
extern Datum btmarkpos(PG_FUNCTION_ARGS);
|
extern Datum btmarkpos(PG_FUNCTION_ARGS);
|
||||||
extern Datum btrestrpos(PG_FUNCTION_ARGS);
|
extern Datum btrestrpos(PG_FUNCTION_ARGS);
|
||||||
|
@ -480,7 +479,7 @@ extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup);
|
||||||
extern ScanKey _bt_mkscankey_nodata(Relation rel);
|
extern ScanKey _bt_mkscankey_nodata(Relation rel);
|
||||||
extern void _bt_freeskey(ScanKey skey);
|
extern void _bt_freeskey(ScanKey skey);
|
||||||
extern void _bt_freestack(BTStack stack);
|
extern void _bt_freestack(BTStack stack);
|
||||||
extern void _bt_orderkeys(IndexScanDesc scan);
|
extern void _bt_preprocess_keys(IndexScanDesc scan);
|
||||||
extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
||||||
ScanDirection dir, bool *continuescan);
|
ScanDirection dir, bool *continuescan);
|
||||||
extern BTItem _bt_formitem(IndexTuple itup);
|
extern BTItem _bt_formitem(IndexTuple itup);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: skey.h,v 1.23 2003/11/09 21:30:37 tgl Exp $
|
* $Id: skey.h,v 1.24 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strategy numbers identify the semantics that particular operators have
|
* Strategy numbers identify the semantics that particular operators have
|
||||||
* with respect to particular operator classes.
|
* with respect to particular operator classes. In some cases a strategy
|
||||||
|
* subtype (an OID) is used as further information.
|
||||||
*/
|
*/
|
||||||
typedef uint16 StrategyNumber;
|
typedef uint16 StrategyNumber;
|
||||||
|
|
||||||
|
@ -47,23 +48,23 @@ typedef uint16 StrategyNumber;
|
||||||
* (The data structure can support unary indexable operators too; in that
|
* (The data structure can support unary indexable operators too; in that
|
||||||
* case sk_argument would go unused. This is not currently implemented.)
|
* case sk_argument would go unused. This is not currently implemented.)
|
||||||
*
|
*
|
||||||
* For an index scan, sk_strategy must be set correctly for the operator.
|
* For an index scan, sk_strategy and sk_subtype must be set correctly for
|
||||||
* When using a ScanKey in a heap scan, sk_strategy is not used and may be
|
* the operator. When using a ScanKey in a heap scan, these fields are not
|
||||||
* set to InvalidStrategy.
|
* used and may be set to InvalidStrategy/InvalidOid.
|
||||||
*
|
*
|
||||||
* Note: in some places, ScanKeys are used as a convenient representation
|
* Note: in some places, ScanKeys are used as a convenient representation
|
||||||
* for the invocation of an access method support procedure. In this case
|
* for the invocation of an access method support procedure. In this case
|
||||||
* sk_strategy is not meaningful, and sk_func may refer to a function that
|
* sk_strategy/sk_subtype are not meaningful, and sk_func may refer to a
|
||||||
* returns something other than boolean.
|
* function that returns something other than boolean.
|
||||||
*/
|
*/
|
||||||
typedef struct ScanKeyData
|
typedef struct ScanKeyData
|
||||||
{
|
{
|
||||||
int sk_flags; /* flags, see below */
|
int sk_flags; /* flags, see below */
|
||||||
AttrNumber sk_attno; /* table or index column number */
|
AttrNumber sk_attno; /* table or index column number */
|
||||||
StrategyNumber sk_strategy; /* operator strategy number */
|
StrategyNumber sk_strategy; /* operator strategy number */
|
||||||
|
Oid sk_subtype; /* strategy subtype */
|
||||||
FmgrInfo sk_func; /* lookup info for function to call */
|
FmgrInfo sk_func; /* lookup info for function to call */
|
||||||
Datum sk_argument; /* data to compare */
|
Datum sk_argument; /* data to compare */
|
||||||
Oid sk_argtype; /* datatype of sk_argument */
|
|
||||||
} ScanKeyData;
|
} ScanKeyData;
|
||||||
|
|
||||||
typedef ScanKeyData *ScanKey;
|
typedef ScanKeyData *ScanKey;
|
||||||
|
@ -76,19 +77,24 @@ typedef ScanKeyData *ScanKey;
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in access/common/scankey.c
|
* prototypes for functions in access/common/scankey.c
|
||||||
*/
|
*/
|
||||||
|
extern void ScanKeyInit(ScanKey entry,
|
||||||
|
AttrNumber attributeNumber,
|
||||||
|
StrategyNumber strategy,
|
||||||
|
RegProcedure procedure,
|
||||||
|
Datum argument);
|
||||||
extern void ScanKeyEntryInitialize(ScanKey entry,
|
extern void ScanKeyEntryInitialize(ScanKey entry,
|
||||||
int flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
StrategyNumber strategy,
|
StrategyNumber strategy,
|
||||||
|
Oid subtype,
|
||||||
RegProcedure procedure,
|
RegProcedure procedure,
|
||||||
Datum argument,
|
Datum argument);
|
||||||
Oid argtype);
|
|
||||||
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
||||||
int flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
StrategyNumber strategy,
|
StrategyNumber strategy,
|
||||||
|
Oid subtype,
|
||||||
FmgrInfo *finfo,
|
FmgrInfo *finfo,
|
||||||
Datum argument,
|
Datum argument);
|
||||||
Oid argtype);
|
|
||||||
|
|
||||||
#endif /* SKEY_H */
|
#endif /* SKEY_H */
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: catversion.h,v 1.210 2003/10/21 16:23:16 tgl Exp $
|
* $Id: catversion.h,v 1.211 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -53,6 +53,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200310211
|
#define CATALOG_VERSION_NO 200311101
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: indexing.h,v 1.79 2003/08/04 02:40:10 momjian Exp $
|
* $Id: indexing.h,v 1.80 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -24,8 +24,8 @@
|
||||||
* macros rather than hardwiring the actual index name.
|
* macros rather than hardwiring the actual index name.
|
||||||
*/
|
*/
|
||||||
#define AccessMethodOperatorIndex "pg_amop_opr_opc_index"
|
#define AccessMethodOperatorIndex "pg_amop_opr_opc_index"
|
||||||
#define AccessMethodStrategyIndex "pg_amop_opc_strategy_index"
|
#define AccessMethodStrategyIndex "pg_amop_opc_strat_index"
|
||||||
#define AccessMethodProcedureIndex "pg_amproc_opc_procnum_index"
|
#define AccessMethodProcedureIndex "pg_amproc_opc_proc_index"
|
||||||
#define AggregateFnoidIndex "pg_aggregate_fnoid_index"
|
#define AggregateFnoidIndex "pg_aggregate_fnoid_index"
|
||||||
#define AmNameIndex "pg_am_name_index"
|
#define AmNameIndex "pg_am_name_index"
|
||||||
#define AmOidIndex "pg_am_oid_index"
|
#define AmOidIndex "pg_am_oid_index"
|
||||||
|
@ -115,9 +115,9 @@ extern void CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple);
|
||||||
DECLARE_UNIQUE_INDEX(pg_aggregate_fnoid_index on pg_aggregate using btree(aggfnoid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_aggregate_fnoid_index on pg_aggregate using btree(aggfnoid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
|
DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
|
||||||
|
DECLARE_UNIQUE_INDEX(pg_amop_opc_strat_index on pg_amop using btree(amopclaid oid_ops, amopsubtype oid_ops, amopstrategy int2_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_amop_opr_opc_index on pg_amop using btree(amopopr oid_ops, amopclaid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_amop_opr_opc_index on pg_amop using btree(amopopr oid_ops, amopclaid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_amop_opc_strategy_index on pg_amop using btree(amopclaid oid_ops, amopstrategy int2_ops));
|
DECLARE_UNIQUE_INDEX(pg_amproc_opc_proc_index on pg_amproc using btree(amopclaid oid_ops, amprocsubtype oid_ops, amprocnum int2_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_amproc_opc_procnum_index on pg_amproc using btree(amopclaid oid_ops, amprocnum int2_ops));
|
|
||||||
DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
|
DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
|
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: namespace.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
|
* $Id: namespace.h,v 1.28 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -42,9 +42,9 @@ typedef struct _OpclassCandidateList
|
||||||
char *opcname_tmp; /* for internal use of namespace lookup */
|
char *opcname_tmp; /* for internal use of namespace lookup */
|
||||||
int pathpos; /* for internal use of namespace lookup */
|
int pathpos; /* for internal use of namespace lookup */
|
||||||
Oid oid; /* the opclass's OID */
|
Oid oid; /* the opclass's OID */
|
||||||
Oid opcintype; /* type of input data for opclass */
|
Oid opcintype; /* type of data indexed by opclass */
|
||||||
bool opcdefault; /* T if opclass is default for opcintype */
|
bool opcdefault; /* T if opclass is default for opcintype */
|
||||||
Oid opckeytype; /* type of index data, or InvalidOid */
|
Oid opckeytype; /* type of data in index, or InvalidOid */
|
||||||
} *OpclassCandidateList;
|
} *OpclassCandidateList;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,24 @@
|
||||||
*
|
*
|
||||||
* The amop table identifies the operators associated with each index opclass.
|
* The amop table identifies the operators associated with each index opclass.
|
||||||
*
|
*
|
||||||
* Note: the primary key for this table is <amopclaid, amopstrategy>.
|
* The primary key for this table is <amopclaid, amopsubtype, amopstrategy>.
|
||||||
|
* amopsubtype is equal to zero for an opclass's "default" operators
|
||||||
|
* (which normally are those that accept the opclass's opcintype on both
|
||||||
|
* left and right sides). Some index AMs allow nondefault operators to
|
||||||
|
* exist for a single strategy --- for example, in the btree AM nondefault
|
||||||
|
* operators can have right-hand input data types different from opcintype,
|
||||||
|
* and their amopsubtype is equal to the right-hand input data type.
|
||||||
|
*
|
||||||
* We also keep a unique index on <amopclaid, amopopr>, so that we can
|
* We also keep a unique index on <amopclaid, amopopr>, so that we can
|
||||||
* use a syscache to quickly answer questions of the form "is this operator
|
* use a syscache to quickly answer questions of the form "is this operator
|
||||||
* in this opclass?". This implies that the same operator cannot be listed
|
* in this opclass?". This implies that the same operator cannot be listed
|
||||||
* for multiple strategy numbers of a single opclass.
|
* for multiple subtypes or strategy numbers of a single opclass.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_amop.h,v 1.55 2003/08/17 19:58:06 tgl Exp $
|
* $Id: pg_amop.h,v 1.56 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -42,6 +49,7 @@
|
||||||
CATALOG(pg_amop) BKI_WITHOUT_OIDS
|
CATALOG(pg_amop) BKI_WITHOUT_OIDS
|
||||||
{
|
{
|
||||||
Oid amopclaid; /* the index opclass this entry is for */
|
Oid amopclaid; /* the index opclass this entry is for */
|
||||||
|
Oid amopsubtype; /* operator subtype, or zero if default */
|
||||||
int2 amopstrategy; /* operator strategy number */
|
int2 amopstrategy; /* operator strategy number */
|
||||||
bool amopreqcheck; /* index hit must be rechecked */
|
bool amopreqcheck; /* index hit must be rechecked */
|
||||||
Oid amopopr; /* the operator's pg_operator OID */
|
Oid amopopr; /* the operator's pg_operator OID */
|
||||||
|
@ -58,11 +66,12 @@ typedef FormData_pg_amop *Form_pg_amop;
|
||||||
* compiler constants for pg_amop
|
* compiler constants for pg_amop
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_amop 4
|
#define Natts_pg_amop 5
|
||||||
#define Anum_pg_amop_amopclaid 1
|
#define Anum_pg_amop_amopclaid 1
|
||||||
#define Anum_pg_amop_amopstrategy 2
|
#define Anum_pg_amop_amopsubtype 2
|
||||||
#define Anum_pg_amop_amopreqcheck 3
|
#define Anum_pg_amop_amopstrategy 3
|
||||||
#define Anum_pg_amop_amopopr 4
|
#define Anum_pg_amop_amopreqcheck 4
|
||||||
|
#define Anum_pg_amop_amopopr 5
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_amop
|
* initial contents of pg_amop
|
||||||
|
@ -73,460 +82,495 @@ typedef FormData_pg_amop *Form_pg_amop;
|
||||||
* rtree box_ops
|
* rtree box_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 425 1 f 493 ));
|
DATA(insert ( 425 0 1 f 493 ));
|
||||||
DATA(insert ( 425 2 f 494 ));
|
DATA(insert ( 425 0 2 f 494 ));
|
||||||
DATA(insert ( 425 3 f 500 ));
|
DATA(insert ( 425 0 3 f 500 ));
|
||||||
DATA(insert ( 425 4 f 495 ));
|
DATA(insert ( 425 0 4 f 495 ));
|
||||||
DATA(insert ( 425 5 f 496 ));
|
DATA(insert ( 425 0 5 f 496 ));
|
||||||
DATA(insert ( 425 6 f 499 ));
|
DATA(insert ( 425 0 6 f 499 ));
|
||||||
DATA(insert ( 425 7 f 498 ));
|
DATA(insert ( 425 0 7 f 498 ));
|
||||||
DATA(insert ( 425 8 f 497 ));
|
DATA(insert ( 425 0 8 f 497 ));
|
||||||
|
|
||||||
/*
|
|
||||||
* rtree bigbox_ops
|
|
||||||
*/
|
|
||||||
|
|
||||||
DATA(insert ( 422 1 f 493 ));
|
|
||||||
DATA(insert ( 422 2 f 494 ));
|
|
||||||
DATA(insert ( 422 3 f 500 ));
|
|
||||||
DATA(insert ( 422 4 f 495 ));
|
|
||||||
DATA(insert ( 422 5 f 496 ));
|
|
||||||
DATA(insert ( 422 6 f 499 ));
|
|
||||||
DATA(insert ( 422 7 f 498 ));
|
|
||||||
DATA(insert ( 422 8 f 497 ));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rtree poly_ops (supports polygons)
|
* rtree poly_ops (supports polygons)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1993 1 f 485 ));
|
DATA(insert ( 1993 0 1 f 485 ));
|
||||||
DATA(insert ( 1993 2 f 486 ));
|
DATA(insert ( 1993 0 2 f 486 ));
|
||||||
DATA(insert ( 1993 3 f 492 ));
|
DATA(insert ( 1993 0 3 f 492 ));
|
||||||
DATA(insert ( 1993 4 f 487 ));
|
DATA(insert ( 1993 0 4 f 487 ));
|
||||||
DATA(insert ( 1993 5 f 488 ));
|
DATA(insert ( 1993 0 5 f 488 ));
|
||||||
DATA(insert ( 1993 6 f 491 ));
|
DATA(insert ( 1993 0 6 f 491 ));
|
||||||
DATA(insert ( 1993 7 f 490 ));
|
DATA(insert ( 1993 0 7 f 490 ));
|
||||||
DATA(insert ( 1993 8 f 489 ));
|
DATA(insert ( 1993 0 8 f 489 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree int2_ops
|
* btree int2_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1976 1 f 95 ));
|
DATA(insert ( 1976 0 1 f 95 ));
|
||||||
DATA(insert ( 1976 2 f 522 ));
|
DATA(insert ( 1976 0 2 f 522 ));
|
||||||
DATA(insert ( 1976 3 f 94 ));
|
DATA(insert ( 1976 0 3 f 94 ));
|
||||||
DATA(insert ( 1976 4 f 524 ));
|
DATA(insert ( 1976 0 4 f 524 ));
|
||||||
DATA(insert ( 1976 5 f 520 ));
|
DATA(insert ( 1976 0 5 f 520 ));
|
||||||
|
/* crosstype operators int24 */
|
||||||
|
DATA(insert ( 1976 23 1 f 534 ));
|
||||||
|
DATA(insert ( 1976 23 2 f 540 ));
|
||||||
|
DATA(insert ( 1976 23 3 f 532 ));
|
||||||
|
DATA(insert ( 1976 23 4 f 542 ));
|
||||||
|
DATA(insert ( 1976 23 5 f 536 ));
|
||||||
|
/* crosstype operators int28 */
|
||||||
|
DATA(insert ( 1976 20 1 f 1864 ));
|
||||||
|
DATA(insert ( 1976 20 2 f 1866 ));
|
||||||
|
DATA(insert ( 1976 20 3 f 1862 ));
|
||||||
|
DATA(insert ( 1976 20 4 f 1867 ));
|
||||||
|
DATA(insert ( 1976 20 5 f 1865 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree int4_ops
|
* btree int4_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1978 1 f 97 ));
|
DATA(insert ( 1978 0 1 f 97 ));
|
||||||
DATA(insert ( 1978 2 f 523 ));
|
DATA(insert ( 1978 0 2 f 523 ));
|
||||||
DATA(insert ( 1978 3 f 96 ));
|
DATA(insert ( 1978 0 3 f 96 ));
|
||||||
DATA(insert ( 1978 4 f 525 ));
|
DATA(insert ( 1978 0 4 f 525 ));
|
||||||
DATA(insert ( 1978 5 f 521 ));
|
DATA(insert ( 1978 0 5 f 521 ));
|
||||||
|
/* crosstype operators int42 */
|
||||||
|
DATA(insert ( 1978 21 1 f 535 ));
|
||||||
|
DATA(insert ( 1978 21 2 f 541 ));
|
||||||
|
DATA(insert ( 1978 21 3 f 533 ));
|
||||||
|
DATA(insert ( 1978 21 4 f 543 ));
|
||||||
|
DATA(insert ( 1978 21 5 f 537 ));
|
||||||
|
/* crosstype operators int48 */
|
||||||
|
DATA(insert ( 1978 20 1 f 37 ));
|
||||||
|
DATA(insert ( 1978 20 2 f 80 ));
|
||||||
|
DATA(insert ( 1978 20 3 f 15 ));
|
||||||
|
DATA(insert ( 1978 20 4 f 82 ));
|
||||||
|
DATA(insert ( 1978 20 5 f 76 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree int8_ops
|
* btree int8_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1980 1 f 412 ));
|
DATA(insert ( 1980 0 1 f 412 ));
|
||||||
DATA(insert ( 1980 2 f 414 ));
|
DATA(insert ( 1980 0 2 f 414 ));
|
||||||
DATA(insert ( 1980 3 f 410 ));
|
DATA(insert ( 1980 0 3 f 410 ));
|
||||||
DATA(insert ( 1980 4 f 415 ));
|
DATA(insert ( 1980 0 4 f 415 ));
|
||||||
DATA(insert ( 1980 5 f 413 ));
|
DATA(insert ( 1980 0 5 f 413 ));
|
||||||
|
/* crosstype operators int82 */
|
||||||
|
DATA(insert ( 1980 21 1 f 1870 ));
|
||||||
|
DATA(insert ( 1980 21 2 f 1872 ));
|
||||||
|
DATA(insert ( 1980 21 3 f 1868 ));
|
||||||
|
DATA(insert ( 1980 21 4 f 1873 ));
|
||||||
|
DATA(insert ( 1980 21 5 f 1871 ));
|
||||||
|
/* crosstype operators int84 */
|
||||||
|
DATA(insert ( 1980 23 1 f 418 ));
|
||||||
|
DATA(insert ( 1980 23 2 f 420 ));
|
||||||
|
DATA(insert ( 1980 23 3 f 416 ));
|
||||||
|
DATA(insert ( 1980 23 4 f 430 ));
|
||||||
|
DATA(insert ( 1980 23 5 f 419 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree oid_ops
|
* btree oid_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1989 1 f 609 ));
|
DATA(insert ( 1989 0 1 f 609 ));
|
||||||
DATA(insert ( 1989 2 f 611 ));
|
DATA(insert ( 1989 0 2 f 611 ));
|
||||||
DATA(insert ( 1989 3 f 607 ));
|
DATA(insert ( 1989 0 3 f 607 ));
|
||||||
DATA(insert ( 1989 4 f 612 ));
|
DATA(insert ( 1989 0 4 f 612 ));
|
||||||
DATA(insert ( 1989 5 f 610 ));
|
DATA(insert ( 1989 0 5 f 610 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree oidvector_ops
|
* btree oidvector_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1991 1 f 645 ));
|
DATA(insert ( 1991 0 1 f 645 ));
|
||||||
DATA(insert ( 1991 2 f 647 ));
|
DATA(insert ( 1991 0 2 f 647 ));
|
||||||
DATA(insert ( 1991 3 f 649 ));
|
DATA(insert ( 1991 0 3 f 649 ));
|
||||||
DATA(insert ( 1991 4 f 648 ));
|
DATA(insert ( 1991 0 4 f 648 ));
|
||||||
DATA(insert ( 1991 5 f 646 ));
|
DATA(insert ( 1991 0 5 f 646 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree float4_ops
|
* btree float4_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1970 1 f 622 ));
|
DATA(insert ( 1970 0 1 f 622 ));
|
||||||
DATA(insert ( 1970 2 f 624 ));
|
DATA(insert ( 1970 0 2 f 624 ));
|
||||||
DATA(insert ( 1970 3 f 620 ));
|
DATA(insert ( 1970 0 3 f 620 ));
|
||||||
DATA(insert ( 1970 4 f 625 ));
|
DATA(insert ( 1970 0 4 f 625 ));
|
||||||
DATA(insert ( 1970 5 f 623 ));
|
DATA(insert ( 1970 0 5 f 623 ));
|
||||||
|
/* crosstype operators float48 */
|
||||||
|
DATA(insert ( 1970 701 1 f 1122 ));
|
||||||
|
DATA(insert ( 1970 701 2 f 1124 ));
|
||||||
|
DATA(insert ( 1970 701 3 f 1120 ));
|
||||||
|
DATA(insert ( 1970 701 4 f 1125 ));
|
||||||
|
DATA(insert ( 1970 701 5 f 1123 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree float8_ops
|
* btree float8_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1972 1 f 672 ));
|
DATA(insert ( 1972 0 1 f 672 ));
|
||||||
DATA(insert ( 1972 2 f 673 ));
|
DATA(insert ( 1972 0 2 f 673 ));
|
||||||
DATA(insert ( 1972 3 f 670 ));
|
DATA(insert ( 1972 0 3 f 670 ));
|
||||||
DATA(insert ( 1972 4 f 675 ));
|
DATA(insert ( 1972 0 4 f 675 ));
|
||||||
DATA(insert ( 1972 5 f 674 ));
|
DATA(insert ( 1972 0 5 f 674 ));
|
||||||
|
/* crosstype operators float84 */
|
||||||
|
DATA(insert ( 1972 700 1 f 1132 ));
|
||||||
|
DATA(insert ( 1972 700 2 f 1134 ));
|
||||||
|
DATA(insert ( 1972 700 3 f 1130 ));
|
||||||
|
DATA(insert ( 1972 700 4 f 1135 ));
|
||||||
|
DATA(insert ( 1972 700 5 f 1133 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree char_ops
|
* btree char_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 429 1 f 631 ));
|
DATA(insert ( 429 0 1 f 631 ));
|
||||||
DATA(insert ( 429 2 f 632 ));
|
DATA(insert ( 429 0 2 f 632 ));
|
||||||
DATA(insert ( 429 3 f 92 ));
|
DATA(insert ( 429 0 3 f 92 ));
|
||||||
DATA(insert ( 429 4 f 634 ));
|
DATA(insert ( 429 0 4 f 634 ));
|
||||||
DATA(insert ( 429 5 f 633 ));
|
DATA(insert ( 429 0 5 f 633 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree name_ops
|
* btree name_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1986 1 f 660 ));
|
DATA(insert ( 1986 0 1 f 660 ));
|
||||||
DATA(insert ( 1986 2 f 661 ));
|
DATA(insert ( 1986 0 2 f 661 ));
|
||||||
DATA(insert ( 1986 3 f 93 ));
|
DATA(insert ( 1986 0 3 f 93 ));
|
||||||
DATA(insert ( 1986 4 f 663 ));
|
DATA(insert ( 1986 0 4 f 663 ));
|
||||||
DATA(insert ( 1986 5 f 662 ));
|
DATA(insert ( 1986 0 5 f 662 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree text_ops
|
* btree text_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1994 1 f 664 ));
|
DATA(insert ( 1994 0 1 f 664 ));
|
||||||
DATA(insert ( 1994 2 f 665 ));
|
DATA(insert ( 1994 0 2 f 665 ));
|
||||||
DATA(insert ( 1994 3 f 98 ));
|
DATA(insert ( 1994 0 3 f 98 ));
|
||||||
DATA(insert ( 1994 4 f 667 ));
|
DATA(insert ( 1994 0 4 f 667 ));
|
||||||
DATA(insert ( 1994 5 f 666 ));
|
DATA(insert ( 1994 0 5 f 666 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree bpchar_ops
|
* btree bpchar_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 426 1 f 1058 ));
|
DATA(insert ( 426 0 1 f 1058 ));
|
||||||
DATA(insert ( 426 2 f 1059 ));
|
DATA(insert ( 426 0 2 f 1059 ));
|
||||||
DATA(insert ( 426 3 f 1054 ));
|
DATA(insert ( 426 0 3 f 1054 ));
|
||||||
DATA(insert ( 426 4 f 1061 ));
|
DATA(insert ( 426 0 4 f 1061 ));
|
||||||
DATA(insert ( 426 5 f 1060 ));
|
DATA(insert ( 426 0 5 f 1060 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree varchar_ops (same operators as text_ops)
|
* btree varchar_ops (same operators as text_ops)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2003 1 f 664 ));
|
DATA(insert ( 2003 0 1 f 664 ));
|
||||||
DATA(insert ( 2003 2 f 665 ));
|
DATA(insert ( 2003 0 2 f 665 ));
|
||||||
DATA(insert ( 2003 3 f 98 ));
|
DATA(insert ( 2003 0 3 f 98 ));
|
||||||
DATA(insert ( 2003 4 f 667 ));
|
DATA(insert ( 2003 0 4 f 667 ));
|
||||||
DATA(insert ( 2003 5 f 666 ));
|
DATA(insert ( 2003 0 5 f 666 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree bytea_ops
|
* btree bytea_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 428 1 f 1957 ));
|
DATA(insert ( 428 0 1 f 1957 ));
|
||||||
DATA(insert ( 428 2 f 1958 ));
|
DATA(insert ( 428 0 2 f 1958 ));
|
||||||
DATA(insert ( 428 3 f 1955 ));
|
DATA(insert ( 428 0 3 f 1955 ));
|
||||||
DATA(insert ( 428 4 f 1960 ));
|
DATA(insert ( 428 0 4 f 1960 ));
|
||||||
DATA(insert ( 428 5 f 1959 ));
|
DATA(insert ( 428 0 5 f 1959 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree abstime_ops
|
* btree abstime_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 421 1 f 562 ));
|
DATA(insert ( 421 0 1 f 562 ));
|
||||||
DATA(insert ( 421 2 f 564 ));
|
DATA(insert ( 421 0 2 f 564 ));
|
||||||
DATA(insert ( 421 3 f 560 ));
|
DATA(insert ( 421 0 3 f 560 ));
|
||||||
DATA(insert ( 421 4 f 565 ));
|
DATA(insert ( 421 0 4 f 565 ));
|
||||||
DATA(insert ( 421 5 f 563 ));
|
DATA(insert ( 421 0 5 f 563 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree date_ops
|
* btree date_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 434 1 f 1095 ));
|
DATA(insert ( 434 0 1 f 1095 ));
|
||||||
DATA(insert ( 434 2 f 1096 ));
|
DATA(insert ( 434 0 2 f 1096 ));
|
||||||
DATA(insert ( 434 3 f 1093 ));
|
DATA(insert ( 434 0 3 f 1093 ));
|
||||||
DATA(insert ( 434 4 f 1098 ));
|
DATA(insert ( 434 0 4 f 1098 ));
|
||||||
DATA(insert ( 434 5 f 1097 ));
|
DATA(insert ( 434 0 5 f 1097 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree time_ops
|
* btree time_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1996 1 f 1110 ));
|
DATA(insert ( 1996 0 1 f 1110 ));
|
||||||
DATA(insert ( 1996 2 f 1111 ));
|
DATA(insert ( 1996 0 2 f 1111 ));
|
||||||
DATA(insert ( 1996 3 f 1108 ));
|
DATA(insert ( 1996 0 3 f 1108 ));
|
||||||
DATA(insert ( 1996 4 f 1113 ));
|
DATA(insert ( 1996 0 4 f 1113 ));
|
||||||
DATA(insert ( 1996 5 f 1112 ));
|
DATA(insert ( 1996 0 5 f 1112 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree timetz_ops
|
* btree timetz_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2000 1 f 1552 ));
|
DATA(insert ( 2000 0 1 f 1552 ));
|
||||||
DATA(insert ( 2000 2 f 1553 ));
|
DATA(insert ( 2000 0 2 f 1553 ));
|
||||||
DATA(insert ( 2000 3 f 1550 ));
|
DATA(insert ( 2000 0 3 f 1550 ));
|
||||||
DATA(insert ( 2000 4 f 1555 ));
|
DATA(insert ( 2000 0 4 f 1555 ));
|
||||||
DATA(insert ( 2000 5 f 1554 ));
|
DATA(insert ( 2000 0 5 f 1554 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree timestamp_ops
|
* btree timestamp_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2039 1 f 2062 ));
|
DATA(insert ( 2039 0 1 f 2062 ));
|
||||||
DATA(insert ( 2039 2 f 2063 ));
|
DATA(insert ( 2039 0 2 f 2063 ));
|
||||||
DATA(insert ( 2039 3 f 2060 ));
|
DATA(insert ( 2039 0 3 f 2060 ));
|
||||||
DATA(insert ( 2039 4 f 2065 ));
|
DATA(insert ( 2039 0 4 f 2065 ));
|
||||||
DATA(insert ( 2039 5 f 2064 ));
|
DATA(insert ( 2039 0 5 f 2064 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree timestamptz_ops
|
* btree timestamptz_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1998 1 f 1322 ));
|
DATA(insert ( 1998 0 1 f 1322 ));
|
||||||
DATA(insert ( 1998 2 f 1323 ));
|
DATA(insert ( 1998 0 2 f 1323 ));
|
||||||
DATA(insert ( 1998 3 f 1320 ));
|
DATA(insert ( 1998 0 3 f 1320 ));
|
||||||
DATA(insert ( 1998 4 f 1325 ));
|
DATA(insert ( 1998 0 4 f 1325 ));
|
||||||
DATA(insert ( 1998 5 f 1324 ));
|
DATA(insert ( 1998 0 5 f 1324 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree interval_ops
|
* btree interval_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1982 1 f 1332 ));
|
DATA(insert ( 1982 0 1 f 1332 ));
|
||||||
DATA(insert ( 1982 2 f 1333 ));
|
DATA(insert ( 1982 0 2 f 1333 ));
|
||||||
DATA(insert ( 1982 3 f 1330 ));
|
DATA(insert ( 1982 0 3 f 1330 ));
|
||||||
DATA(insert ( 1982 4 f 1335 ));
|
DATA(insert ( 1982 0 4 f 1335 ));
|
||||||
DATA(insert ( 1982 5 f 1334 ));
|
DATA(insert ( 1982 0 5 f 1334 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree macaddr
|
* btree macaddr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1984 1 f 1222 ));
|
DATA(insert ( 1984 0 1 f 1222 ));
|
||||||
DATA(insert ( 1984 2 f 1223 ));
|
DATA(insert ( 1984 0 2 f 1223 ));
|
||||||
DATA(insert ( 1984 3 f 1220 ));
|
DATA(insert ( 1984 0 3 f 1220 ));
|
||||||
DATA(insert ( 1984 4 f 1225 ));
|
DATA(insert ( 1984 0 4 f 1225 ));
|
||||||
DATA(insert ( 1984 5 f 1224 ));
|
DATA(insert ( 1984 0 5 f 1224 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree inet
|
* btree inet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1974 1 f 1203 ));
|
DATA(insert ( 1974 0 1 f 1203 ));
|
||||||
DATA(insert ( 1974 2 f 1204 ));
|
DATA(insert ( 1974 0 2 f 1204 ));
|
||||||
DATA(insert ( 1974 3 f 1201 ));
|
DATA(insert ( 1974 0 3 f 1201 ));
|
||||||
DATA(insert ( 1974 4 f 1206 ));
|
DATA(insert ( 1974 0 4 f 1206 ));
|
||||||
DATA(insert ( 1974 5 f 1205 ));
|
DATA(insert ( 1974 0 5 f 1205 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree cidr
|
* btree cidr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 432 1 f 822 ));
|
DATA(insert ( 432 0 1 f 822 ));
|
||||||
DATA(insert ( 432 2 f 823 ));
|
DATA(insert ( 432 0 2 f 823 ));
|
||||||
DATA(insert ( 432 3 f 820 ));
|
DATA(insert ( 432 0 3 f 820 ));
|
||||||
DATA(insert ( 432 4 f 825 ));
|
DATA(insert ( 432 0 4 f 825 ));
|
||||||
DATA(insert ( 432 5 f 824 ));
|
DATA(insert ( 432 0 5 f 824 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree numeric
|
* btree numeric
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 1988 1 f 1754 ));
|
DATA(insert ( 1988 0 1 f 1754 ));
|
||||||
DATA(insert ( 1988 2 f 1755 ));
|
DATA(insert ( 1988 0 2 f 1755 ));
|
||||||
DATA(insert ( 1988 3 f 1752 ));
|
DATA(insert ( 1988 0 3 f 1752 ));
|
||||||
DATA(insert ( 1988 4 f 1757 ));
|
DATA(insert ( 1988 0 4 f 1757 ));
|
||||||
DATA(insert ( 1988 5 f 1756 ));
|
DATA(insert ( 1988 0 5 f 1756 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree bool
|
* btree bool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 424 1 f 58 ));
|
DATA(insert ( 424 0 1 f 58 ));
|
||||||
DATA(insert ( 424 2 f 1694 ));
|
DATA(insert ( 424 0 2 f 1694 ));
|
||||||
DATA(insert ( 424 3 f 91 ));
|
DATA(insert ( 424 0 3 f 91 ));
|
||||||
DATA(insert ( 424 4 f 1695 ));
|
DATA(insert ( 424 0 4 f 1695 ));
|
||||||
DATA(insert ( 424 5 f 59 ));
|
DATA(insert ( 424 0 5 f 59 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree bit
|
* btree bit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 423 1 f 1786 ));
|
DATA(insert ( 423 0 1 f 1786 ));
|
||||||
DATA(insert ( 423 2 f 1788 ));
|
DATA(insert ( 423 0 2 f 1788 ));
|
||||||
DATA(insert ( 423 3 f 1784 ));
|
DATA(insert ( 423 0 3 f 1784 ));
|
||||||
DATA(insert ( 423 4 f 1789 ));
|
DATA(insert ( 423 0 4 f 1789 ));
|
||||||
DATA(insert ( 423 5 f 1787 ));
|
DATA(insert ( 423 0 5 f 1787 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree varbit
|
* btree varbit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2002 1 f 1806 ));
|
DATA(insert ( 2002 0 1 f 1806 ));
|
||||||
DATA(insert ( 2002 2 f 1808 ));
|
DATA(insert ( 2002 0 2 f 1808 ));
|
||||||
DATA(insert ( 2002 3 f 1804 ));
|
DATA(insert ( 2002 0 3 f 1804 ));
|
||||||
DATA(insert ( 2002 4 f 1809 ));
|
DATA(insert ( 2002 0 4 f 1809 ));
|
||||||
DATA(insert ( 2002 5 f 1807 ));
|
DATA(insert ( 2002 0 5 f 1807 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree text pattern
|
* btree text pattern
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2095 1 f 2314 ));
|
DATA(insert ( 2095 0 1 f 2314 ));
|
||||||
DATA(insert ( 2095 2 f 2315 ));
|
DATA(insert ( 2095 0 2 f 2315 ));
|
||||||
DATA(insert ( 2095 3 f 2316 ));
|
DATA(insert ( 2095 0 3 f 2316 ));
|
||||||
DATA(insert ( 2095 4 f 2317 ));
|
DATA(insert ( 2095 0 4 f 2317 ));
|
||||||
DATA(insert ( 2095 5 f 2318 ));
|
DATA(insert ( 2095 0 5 f 2318 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree varchar pattern (same operators as text)
|
* btree varchar pattern (same operators as text)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2096 1 f 2314 ));
|
DATA(insert ( 2096 0 1 f 2314 ));
|
||||||
DATA(insert ( 2096 2 f 2315 ));
|
DATA(insert ( 2096 0 2 f 2315 ));
|
||||||
DATA(insert ( 2096 3 f 2316 ));
|
DATA(insert ( 2096 0 3 f 2316 ));
|
||||||
DATA(insert ( 2096 4 f 2317 ));
|
DATA(insert ( 2096 0 4 f 2317 ));
|
||||||
DATA(insert ( 2096 5 f 2318 ));
|
DATA(insert ( 2096 0 5 f 2318 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree bpchar pattern
|
* btree bpchar pattern
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2097 1 f 2326 ));
|
DATA(insert ( 2097 0 1 f 2326 ));
|
||||||
DATA(insert ( 2097 2 f 2327 ));
|
DATA(insert ( 2097 0 2 f 2327 ));
|
||||||
DATA(insert ( 2097 3 f 2328 ));
|
DATA(insert ( 2097 0 3 f 2328 ));
|
||||||
DATA(insert ( 2097 4 f 2329 ));
|
DATA(insert ( 2097 0 4 f 2329 ));
|
||||||
DATA(insert ( 2097 5 f 2330 ));
|
DATA(insert ( 2097 0 5 f 2330 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree name pattern
|
* btree name pattern
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2098 1 f 2332 ));
|
DATA(insert ( 2098 0 1 f 2332 ));
|
||||||
DATA(insert ( 2098 2 f 2333 ));
|
DATA(insert ( 2098 0 2 f 2333 ));
|
||||||
DATA(insert ( 2098 3 f 2334 ));
|
DATA(insert ( 2098 0 3 f 2334 ));
|
||||||
DATA(insert ( 2098 4 f 2335 ));
|
DATA(insert ( 2098 0 4 f 2335 ));
|
||||||
DATA(insert ( 2098 5 f 2336 ));
|
DATA(insert ( 2098 0 5 f 2336 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree money_ops
|
* btree money_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2099 1 f 902 ));
|
DATA(insert ( 2099 0 1 f 902 ));
|
||||||
DATA(insert ( 2099 2 f 904 ));
|
DATA(insert ( 2099 0 2 f 904 ));
|
||||||
DATA(insert ( 2099 3 f 900 ));
|
DATA(insert ( 2099 0 3 f 900 ));
|
||||||
DATA(insert ( 2099 4 f 905 ));
|
DATA(insert ( 2099 0 4 f 905 ));
|
||||||
DATA(insert ( 2099 5 f 903 ));
|
DATA(insert ( 2099 0 5 f 903 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree reltime_ops
|
* btree reltime_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2233 1 f 568 ));
|
DATA(insert ( 2233 0 1 f 568 ));
|
||||||
DATA(insert ( 2233 2 f 570 ));
|
DATA(insert ( 2233 0 2 f 570 ));
|
||||||
DATA(insert ( 2233 3 f 566 ));
|
DATA(insert ( 2233 0 3 f 566 ));
|
||||||
DATA(insert ( 2233 4 f 569 ));
|
DATA(insert ( 2233 0 4 f 571 ));
|
||||||
DATA(insert ( 2233 5 f 571 ));
|
DATA(insert ( 2233 0 5 f 569 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree tinterval_ops
|
* btree tinterval_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 2234 1 f 813 ));
|
DATA(insert ( 2234 0 1 f 813 ));
|
||||||
DATA(insert ( 2234 2 f 815 ));
|
DATA(insert ( 2234 0 2 f 815 ));
|
||||||
DATA(insert ( 2234 3 f 811 ));
|
DATA(insert ( 2234 0 3 f 811 ));
|
||||||
DATA(insert ( 2234 4 f 814 ));
|
DATA(insert ( 2234 0 4 f 816 ));
|
||||||
DATA(insert ( 2234 5 f 816 ));
|
DATA(insert ( 2234 0 5 f 814 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* btree array_ops
|
* btree array_ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( 397 1 f 1072 ));
|
DATA(insert ( 397 0 1 f 1072 ));
|
||||||
DATA(insert ( 397 2 f 1074 ));
|
DATA(insert ( 397 0 2 f 1074 ));
|
||||||
DATA(insert ( 397 3 f 1070 ));
|
DATA(insert ( 397 0 3 f 1070 ));
|
||||||
DATA(insert ( 397 4 f 1075 ));
|
DATA(insert ( 397 0 4 f 1075 ));
|
||||||
DATA(insert ( 397 5 f 1073 ));
|
DATA(insert ( 397 0 5 f 1073 ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hash index _ops
|
* hash index _ops
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* bpchar_ops */
|
/* bpchar_ops */
|
||||||
DATA(insert ( 427 1 f 1054 ));
|
DATA(insert ( 427 0 1 f 1054 ));
|
||||||
/* char_ops */
|
/* char_ops */
|
||||||
DATA(insert ( 431 1 f 92 ));
|
DATA(insert ( 431 0 1 f 92 ));
|
||||||
/* cidr_ops */
|
/* cidr_ops */
|
||||||
DATA(insert ( 433 1 f 820 ));
|
DATA(insert ( 433 0 1 f 820 ));
|
||||||
/* date_ops */
|
/* date_ops */
|
||||||
DATA(insert ( 435 1 f 1093 ));
|
DATA(insert ( 435 0 1 f 1093 ));
|
||||||
/* float4_ops */
|
/* float4_ops */
|
||||||
DATA(insert ( 1971 1 f 620 ));
|
DATA(insert ( 1971 0 1 f 620 ));
|
||||||
/* float8_ops */
|
/* float8_ops */
|
||||||
DATA(insert ( 1973 1 f 670 ));
|
DATA(insert ( 1973 0 1 f 670 ));
|
||||||
/* inet_ops */
|
/* inet_ops */
|
||||||
DATA(insert ( 1975 1 f 1201 ));
|
DATA(insert ( 1975 0 1 f 1201 ));
|
||||||
/* int2_ops */
|
/* int2_ops */
|
||||||
DATA(insert ( 1977 1 f 94 ));
|
DATA(insert ( 1977 0 1 f 94 ));
|
||||||
/* int4_ops */
|
/* int4_ops */
|
||||||
DATA(insert ( 1979 1 f 96 ));
|
DATA(insert ( 1979 0 1 f 96 ));
|
||||||
/* int8_ops */
|
/* int8_ops */
|
||||||
DATA(insert ( 1981 1 f 410 ));
|
DATA(insert ( 1981 0 1 f 410 ));
|
||||||
/* interval_ops */
|
/* interval_ops */
|
||||||
DATA(insert ( 1983 1 f 1330 ));
|
DATA(insert ( 1983 0 1 f 1330 ));
|
||||||
/* macaddr_ops */
|
/* macaddr_ops */
|
||||||
DATA(insert ( 1985 1 f 1220 ));
|
DATA(insert ( 1985 0 1 f 1220 ));
|
||||||
/* name_ops */
|
/* name_ops */
|
||||||
DATA(insert ( 1987 1 f 93 ));
|
DATA(insert ( 1987 0 1 f 93 ));
|
||||||
/* oid_ops */
|
/* oid_ops */
|
||||||
DATA(insert ( 1990 1 f 607 ));
|
DATA(insert ( 1990 0 1 f 607 ));
|
||||||
/* oidvector_ops */
|
/* oidvector_ops */
|
||||||
DATA(insert ( 1992 1 f 649 ));
|
DATA(insert ( 1992 0 1 f 649 ));
|
||||||
/* text_ops */
|
/* text_ops */
|
||||||
DATA(insert ( 1995 1 f 98 ));
|
DATA(insert ( 1995 0 1 f 98 ));
|
||||||
/* time_ops */
|
/* time_ops */
|
||||||
DATA(insert ( 1997 1 f 1108 ));
|
DATA(insert ( 1997 0 1 f 1108 ));
|
||||||
/* timestamptz_ops */
|
/* timestamptz_ops */
|
||||||
DATA(insert ( 1999 1 f 1320 ));
|
DATA(insert ( 1999 0 1 f 1320 ));
|
||||||
/* timetz_ops */
|
/* timetz_ops */
|
||||||
DATA(insert ( 2001 1 f 1550 ));
|
DATA(insert ( 2001 0 1 f 1550 ));
|
||||||
/* varchar_ops */
|
/* varchar_ops */
|
||||||
DATA(insert ( 2004 1 f 98 ));
|
DATA(insert ( 2004 0 1 f 98 ));
|
||||||
/* timestamp_ops */
|
/* timestamp_ops */
|
||||||
DATA(insert ( 2040 1 f 2060 ));
|
DATA(insert ( 2040 0 1 f 2060 ));
|
||||||
/* bool_ops */
|
/* bool_ops */
|
||||||
DATA(insert ( 2222 1 f 91 ));
|
DATA(insert ( 2222 0 1 f 91 ));
|
||||||
/* bytea_ops */
|
/* bytea_ops */
|
||||||
DATA(insert ( 2223 1 f 1955 ));
|
DATA(insert ( 2223 0 1 f 1955 ));
|
||||||
/* int2vector_ops */
|
/* int2vector_ops */
|
||||||
DATA(insert ( 2224 1 f 386 ));
|
DATA(insert ( 2224 0 1 f 386 ));
|
||||||
/* xid_ops */
|
/* xid_ops */
|
||||||
DATA(insert ( 2225 1 f 352 ));
|
DATA(insert ( 2225 0 1 f 352 ));
|
||||||
/* cid_ops */
|
/* cid_ops */
|
||||||
DATA(insert ( 2226 1 f 385 ));
|
DATA(insert ( 2226 0 1 f 385 ));
|
||||||
/* abstime_ops */
|
/* abstime_ops */
|
||||||
DATA(insert ( 2227 1 f 560 ));
|
DATA(insert ( 2227 0 1 f 560 ));
|
||||||
/* reltime_ops */
|
/* reltime_ops */
|
||||||
DATA(insert ( 2228 1 f 566 ));
|
DATA(insert ( 2228 0 1 f 566 ));
|
||||||
/* text_pattern_ops */
|
/* text_pattern_ops */
|
||||||
DATA(insert ( 2229 1 f 2316 ));
|
DATA(insert ( 2229 0 1 f 2316 ));
|
||||||
/* varchar_pattern_ops */
|
/* varchar_pattern_ops */
|
||||||
DATA(insert ( 2230 1 f 2316 ));
|
DATA(insert ( 2230 0 1 f 2316 ));
|
||||||
/* bpchar_pattern_ops */
|
/* bpchar_pattern_ops */
|
||||||
DATA(insert ( 2231 1 f 2328 ));
|
DATA(insert ( 2231 0 1 f 2328 ));
|
||||||
/* name_pattern_ops */
|
/* name_pattern_ops */
|
||||||
DATA(insert ( 2232 1 f 2334 ));
|
DATA(insert ( 2232 0 1 f 2334 ));
|
||||||
/* aclitem_ops */
|
/* aclitem_ops */
|
||||||
DATA(insert ( 2235 1 f 974 ));
|
DATA(insert ( 2235 0 1 f 974 ));
|
||||||
|
|
||||||
#endif /* PG_AMOP_H */
|
#endif /* PG_AMOP_H */
|
||||||
|
|
|
@ -6,15 +6,20 @@
|
||||||
*
|
*
|
||||||
* The amproc table identifies support procedures associated with index
|
* The amproc table identifies support procedures associated with index
|
||||||
* opclasses. These procedures can't be listed in pg_amop since they are
|
* opclasses. These procedures can't be listed in pg_amop since they are
|
||||||
* not associated with indexable operators for the opclass.
|
* not the implementation of any indexable operator for the opclass.
|
||||||
*
|
*
|
||||||
* Note: the primary key for this table is <amopclaid, amprocnum>.
|
* The primary key for this table is <amopclaid, amprocsubtype, amprocnum>.
|
||||||
|
* amprocsubtype is equal to zero for an opclass's "default" procedures.
|
||||||
|
* Usually a nondefault amprocsubtype indicates a support procedure to be
|
||||||
|
* used with operators having the same nondefault amopsubtype. The exact
|
||||||
|
* behavior depends on the index AM, however, and some don't pay attention
|
||||||
|
* to subtype at all.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_amproc.h,v 1.44 2003/08/17 19:58:06 tgl Exp $
|
* $Id: pg_amproc.h,v 1.45 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -40,6 +45,7 @@
|
||||||
CATALOG(pg_amproc) BKI_WITHOUT_OIDS
|
CATALOG(pg_amproc) BKI_WITHOUT_OIDS
|
||||||
{
|
{
|
||||||
Oid amopclaid; /* the index opclass this entry is for */
|
Oid amopclaid; /* the index opclass this entry is for */
|
||||||
|
Oid amprocsubtype; /* procedure subtype, or zero if default */
|
||||||
int2 amprocnum; /* support procedure index */
|
int2 amprocnum; /* support procedure index */
|
||||||
regproc amproc; /* OID of the proc */
|
regproc amproc; /* OID of the proc */
|
||||||
} FormData_pg_amproc;
|
} FormData_pg_amproc;
|
||||||
|
@ -55,10 +61,11 @@ typedef FormData_pg_amproc *Form_pg_amproc;
|
||||||
* compiler constants for pg_amproc
|
* compiler constants for pg_amproc
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_amproc 3
|
#define Natts_pg_amproc 4
|
||||||
#define Anum_pg_amproc_amopclaid 1
|
#define Anum_pg_amproc_amopclaid 1
|
||||||
#define Anum_pg_amproc_amprocnum 2
|
#define Anum_pg_amproc_amprocsubtype 2
|
||||||
#define Anum_pg_amproc_amproc 3
|
#define Anum_pg_amproc_amprocnum 3
|
||||||
|
#define Anum_pg_amproc_amproc 4
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_amproc
|
* initial contents of pg_amproc
|
||||||
|
@ -66,88 +73,93 @@ typedef FormData_pg_amproc *Form_pg_amproc;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* rtree */
|
/* rtree */
|
||||||
DATA(insert ( 422 1 193 ));
|
DATA(insert ( 425 0 1 193 ));
|
||||||
DATA(insert ( 422 2 194 ));
|
DATA(insert ( 425 0 2 194 ));
|
||||||
DATA(insert ( 422 3 196 ));
|
DATA(insert ( 425 0 3 195 ));
|
||||||
DATA(insert ( 425 1 193 ));
|
DATA(insert ( 1993 0 1 197 ));
|
||||||
DATA(insert ( 425 2 194 ));
|
DATA(insert ( 1993 0 2 198 ));
|
||||||
DATA(insert ( 425 3 195 ));
|
DATA(insert ( 1993 0 3 199 ));
|
||||||
DATA(insert ( 1993 1 197 ));
|
|
||||||
DATA(insert ( 1993 2 198 ));
|
|
||||||
DATA(insert ( 1993 3 199 ));
|
|
||||||
|
|
||||||
|
|
||||||
/* btree */
|
/* btree */
|
||||||
DATA(insert ( 397 1 382 ));
|
DATA(insert ( 397 0 1 382 ));
|
||||||
DATA(insert ( 421 1 357 ));
|
DATA(insert ( 421 0 1 357 ));
|
||||||
DATA(insert ( 423 1 1596 ));
|
DATA(insert ( 423 0 1 1596 ));
|
||||||
DATA(insert ( 424 1 1693 ));
|
DATA(insert ( 424 0 1 1693 ));
|
||||||
DATA(insert ( 426 1 1078 ));
|
DATA(insert ( 426 0 1 1078 ));
|
||||||
DATA(insert ( 428 1 1954 ));
|
DATA(insert ( 428 0 1 1954 ));
|
||||||
DATA(insert ( 429 1 358 ));
|
DATA(insert ( 429 0 1 358 ));
|
||||||
DATA(insert ( 432 1 926 ));
|
DATA(insert ( 432 0 1 926 ));
|
||||||
DATA(insert ( 434 1 1092 ));
|
DATA(insert ( 434 0 1 1092 ));
|
||||||
DATA(insert ( 1970 1 354 ));
|
DATA(insert ( 1970 0 1 354 ));
|
||||||
DATA(insert ( 1972 1 355 ));
|
DATA(insert ( 1970 701 1 2194 ));
|
||||||
DATA(insert ( 1974 1 926 ));
|
DATA(insert ( 1972 0 1 355 ));
|
||||||
DATA(insert ( 1976 1 350 ));
|
DATA(insert ( 1972 700 1 2195 ));
|
||||||
DATA(insert ( 1978 1 351 ));
|
DATA(insert ( 1974 0 1 926 ));
|
||||||
DATA(insert ( 1980 1 842 ));
|
DATA(insert ( 1976 0 1 350 ));
|
||||||
DATA(insert ( 1982 1 1315 ));
|
DATA(insert ( 1976 23 1 2190 ));
|
||||||
DATA(insert ( 1984 1 836 ));
|
DATA(insert ( 1976 20 1 2192 ));
|
||||||
DATA(insert ( 1986 1 359 ));
|
DATA(insert ( 1978 0 1 351 ));
|
||||||
DATA(insert ( 1988 1 1769 ));
|
DATA(insert ( 1978 20 1 2188 ));
|
||||||
DATA(insert ( 1989 1 356 ));
|
DATA(insert ( 1978 21 1 2191 ));
|
||||||
DATA(insert ( 1991 1 404 ));
|
DATA(insert ( 1980 0 1 842 ));
|
||||||
DATA(insert ( 1994 1 360 ));
|
DATA(insert ( 1980 23 1 2189 ));
|
||||||
DATA(insert ( 1996 1 1107 ));
|
DATA(insert ( 1980 21 1 2193 ));
|
||||||
DATA(insert ( 1998 1 1314 ));
|
DATA(insert ( 1982 0 1 1315 ));
|
||||||
DATA(insert ( 2000 1 1358 ));
|
DATA(insert ( 1984 0 1 836 ));
|
||||||
DATA(insert ( 2002 1 1672 ));
|
DATA(insert ( 1986 0 1 359 ));
|
||||||
DATA(insert ( 2003 1 360 ));
|
DATA(insert ( 1988 0 1 1769 ));
|
||||||
DATA(insert ( 2039 1 2045 ));
|
DATA(insert ( 1989 0 1 356 ));
|
||||||
DATA(insert ( 2095 1 2166 ));
|
DATA(insert ( 1991 0 1 404 ));
|
||||||
DATA(insert ( 2096 1 2166 ));
|
DATA(insert ( 1994 0 1 360 ));
|
||||||
DATA(insert ( 2097 1 2180 ));
|
DATA(insert ( 1996 0 1 1107 ));
|
||||||
DATA(insert ( 2098 1 2187 ));
|
DATA(insert ( 1998 0 1 1314 ));
|
||||||
DATA(insert ( 2099 1 377 ));
|
DATA(insert ( 2000 0 1 1358 ));
|
||||||
DATA(insert ( 2233 1 380 ));
|
DATA(insert ( 2002 0 1 1672 ));
|
||||||
DATA(insert ( 2234 1 381 ));
|
DATA(insert ( 2003 0 1 360 ));
|
||||||
|
DATA(insert ( 2039 0 1 2045 ));
|
||||||
|
DATA(insert ( 2095 0 1 2166 ));
|
||||||
|
DATA(insert ( 2096 0 1 2166 ));
|
||||||
|
DATA(insert ( 2097 0 1 2180 ));
|
||||||
|
DATA(insert ( 2098 0 1 2187 ));
|
||||||
|
DATA(insert ( 2099 0 1 377 ));
|
||||||
|
DATA(insert ( 2233 0 1 380 ));
|
||||||
|
DATA(insert ( 2234 0 1 381 ));
|
||||||
|
|
||||||
|
|
||||||
/* hash */
|
/* hash */
|
||||||
DATA(insert ( 427 1 1080 ));
|
DATA(insert ( 427 0 1 1080 ));
|
||||||
DATA(insert ( 431 1 454 ));
|
DATA(insert ( 431 0 1 454 ));
|
||||||
DATA(insert ( 433 1 456 ));
|
DATA(insert ( 433 0 1 456 ));
|
||||||
DATA(insert ( 435 1 450 ));
|
DATA(insert ( 435 0 1 450 ));
|
||||||
DATA(insert ( 1971 1 451 ));
|
DATA(insert ( 1971 0 1 451 ));
|
||||||
DATA(insert ( 1973 1 452 ));
|
DATA(insert ( 1973 0 1 452 ));
|
||||||
DATA(insert ( 1975 1 456 ));
|
DATA(insert ( 1975 0 1 456 ));
|
||||||
DATA(insert ( 1977 1 449 ));
|
DATA(insert ( 1977 0 1 449 ));
|
||||||
DATA(insert ( 1979 1 450 ));
|
DATA(insert ( 1979 0 1 450 ));
|
||||||
DATA(insert ( 1981 1 949 ));
|
DATA(insert ( 1981 0 1 949 ));
|
||||||
DATA(insert ( 1983 1 1697 ));
|
DATA(insert ( 1983 0 1 1697 ));
|
||||||
DATA(insert ( 1985 1 399 ));
|
DATA(insert ( 1985 0 1 399 ));
|
||||||
DATA(insert ( 1987 1 455 ));
|
DATA(insert ( 1987 0 1 455 ));
|
||||||
DATA(insert ( 1990 1 453 ));
|
DATA(insert ( 1990 0 1 453 ));
|
||||||
DATA(insert ( 1992 1 457 ));
|
DATA(insert ( 1992 0 1 457 ));
|
||||||
DATA(insert ( 1995 1 400 ));
|
DATA(insert ( 1995 0 1 400 ));
|
||||||
DATA(insert ( 1997 1 452 ));
|
DATA(insert ( 1997 0 1 452 ));
|
||||||
DATA(insert ( 1999 1 452 ));
|
DATA(insert ( 1999 0 1 452 ));
|
||||||
DATA(insert ( 2001 1 1696 ));
|
DATA(insert ( 2001 0 1 1696 ));
|
||||||
DATA(insert ( 2004 1 400 ));
|
DATA(insert ( 2004 0 1 400 ));
|
||||||
DATA(insert ( 2040 1 452 ));
|
DATA(insert ( 2040 0 1 452 ));
|
||||||
DATA(insert ( 2222 1 454 ));
|
DATA(insert ( 2222 0 1 454 ));
|
||||||
DATA(insert ( 2223 1 456 ));
|
DATA(insert ( 2223 0 1 456 ));
|
||||||
DATA(insert ( 2224 1 398 ));
|
DATA(insert ( 2224 0 1 398 ));
|
||||||
DATA(insert ( 2225 1 450 ));
|
DATA(insert ( 2225 0 1 450 ));
|
||||||
DATA(insert ( 2226 1 450 ));
|
DATA(insert ( 2226 0 1 450 ));
|
||||||
DATA(insert ( 2227 1 450 ));
|
DATA(insert ( 2227 0 1 450 ));
|
||||||
DATA(insert ( 2228 1 450 ));
|
DATA(insert ( 2228 0 1 450 ));
|
||||||
DATA(insert ( 2229 1 456 ));
|
DATA(insert ( 2229 0 1 456 ));
|
||||||
DATA(insert ( 2230 1 456 ));
|
DATA(insert ( 2230 0 1 456 ));
|
||||||
DATA(insert ( 2231 1 456 ));
|
DATA(insert ( 2231 0 1 456 ));
|
||||||
DATA(insert ( 2232 1 455 ));
|
DATA(insert ( 2232 0 1 455 ));
|
||||||
DATA(insert ( 2235 1 329 ));
|
DATA(insert ( 2235 0 1 329 ));
|
||||||
|
|
||||||
#endif /* PG_AMPROC_H */
|
#endif /* PG_AMPROC_H */
|
||||||
|
|
|
@ -16,17 +16,18 @@
|
||||||
* such an index.
|
* such an index.
|
||||||
*
|
*
|
||||||
* Normally opckeytype = InvalidOid (zero), indicating that the data stored
|
* Normally opckeytype = InvalidOid (zero), indicating that the data stored
|
||||||
* in the index is the same as the input data. If opckeytype is nonzero
|
* in the index is the same as the data in the indexed column. If opckeytype
|
||||||
* then it indicates that a conversion step is needed to produce the stored
|
* is nonzero then it indicates that a conversion step is needed to produce
|
||||||
* index data, which will be of type opckeytype (which might be the same or
|
* the stored index data, which will be of type opckeytype (which might be
|
||||||
* different from the input data). Performing such a conversion is the
|
* the same or different from the input datatype). Performing such a
|
||||||
* responsibility of the index access method --- not all AMs support this.
|
* conversion is the responsibility of the index access method --- not all
|
||||||
|
* AMs support this.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_opclass.h,v 1.57 2003/08/17 19:58:06 tgl Exp $
|
* $Id: pg_opclass.h,v 1.58 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -56,9 +57,9 @@ CATALOG(pg_opclass)
|
||||||
NameData opcname; /* name of this opclass */
|
NameData opcname; /* name of this opclass */
|
||||||
Oid opcnamespace; /* namespace of this opclass */
|
Oid opcnamespace; /* namespace of this opclass */
|
||||||
int4 opcowner; /* opclass owner */
|
int4 opcowner; /* opclass owner */
|
||||||
Oid opcintype; /* type of input data for opclass */
|
Oid opcintype; /* type of data indexed by opclass */
|
||||||
bool opcdefault; /* T if opclass is default for opcintype */
|
bool opcdefault; /* T if opclass is default for opcintype */
|
||||||
Oid opckeytype; /* type of index data, or InvalidOid */
|
Oid opckeytype; /* type of data in index, or InvalidOid */
|
||||||
} FormData_pg_opclass;
|
} FormData_pg_opclass;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
@ -89,7 +90,6 @@ typedef FormData_pg_opclass *Form_pg_opclass;
|
||||||
DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID 702 t 0 ));
|
DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID 702 t 0 ));
|
||||||
DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID 2277 t 0 ));
|
DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID 2277 t 0 ));
|
||||||
#define ARRAY_BTREE_OPS_OID 397
|
#define ARRAY_BTREE_OPS_OID 397
|
||||||
DATA(insert OID = 422 ( 402 bigbox_ops PGNSP PGUID 603 f 0 ));
|
|
||||||
DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 ));
|
DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 ));
|
||||||
DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 ));
|
DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 ));
|
||||||
DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 ));
|
DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 ));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_proc.h,v 1.314 2003/10/21 16:23:16 tgl Exp $
|
* $Id: pg_proc.h,v 1.315 2003/11/12 21:15:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
|
@ -400,8 +400,6 @@ DATA(insert OID = 194 ( rt_box_inter PGNSP PGUID 12 f f t f i 2 2278 "603 60
|
||||||
DESCR("r-tree");
|
DESCR("r-tree");
|
||||||
DATA(insert OID = 195 ( rt_box_size PGNSP PGUID 12 f f t f i 2 2278 "603 2281" rt_box_size - _null_ ));
|
DATA(insert OID = 195 ( rt_box_size PGNSP PGUID 12 f f t f i 2 2278 "603 2281" rt_box_size - _null_ ));
|
||||||
DESCR("r-tree");
|
DESCR("r-tree");
|
||||||
DATA(insert OID = 196 ( rt_bigbox_size PGNSP PGUID 12 f f t f i 2 2278 "603 2281" rt_bigbox_size - _null_ ));
|
|
||||||
DESCR("r-tree");
|
|
||||||
DATA(insert OID = 197 ( rt_poly_union PGNSP PGUID 12 f f t f i 2 604 "604 604" rt_poly_union - _null_ ));
|
DATA(insert OID = 197 ( rt_poly_union PGNSP PGUID 12 f f t f i 2 604 "604 604" rt_poly_union - _null_ ));
|
||||||
DESCR("r-tree");
|
DESCR("r-tree");
|
||||||
DATA(insert OID = 198 ( rt_poly_inter PGNSP PGUID 12 f f t f i 2 2278 "604 604" rt_poly_inter - _null_ ));
|
DATA(insert OID = 198 ( rt_poly_inter PGNSP PGUID 12 f f t f i 2 2278 "604 604" rt_poly_inter - _null_ ));
|
||||||
|
@ -3075,6 +3073,15 @@ DATA(insert OID = 2185 ( name_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "19 19" n
|
||||||
DATA(insert OID = 2186 ( name_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_ne - _null_ ));
|
DATA(insert OID = 2186 ( name_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_ne - _null_ ));
|
||||||
DATA(insert OID = 2187 ( btname_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btname_pattern_cmp - _null_ ));
|
DATA(insert OID = 2187 ( btname_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btname_pattern_cmp - _null_ ));
|
||||||
|
|
||||||
|
DATA(insert OID = 2188 ( btint48cmp PGNSP PGUID 12 f f t f i 2 23 "23 20" btint48cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2189 ( btint84cmp PGNSP PGUID 12 f f t f i 2 23 "20 23" btint84cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2190 ( btint24cmp PGNSP PGUID 12 f f t f i 2 23 "21 23" btint24cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2191 ( btint42cmp PGNSP PGUID 12 f f t f i 2 23 "23 21" btint42cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2192 ( btint28cmp PGNSP PGUID 12 f f t f i 2 23 "21 20" btint28cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2193 ( btint82cmp PGNSP PGUID 12 f f t f i 2 23 "20 21" btint82cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2194 ( btfloat48cmp PGNSP PGUID 12 f f t f i 2 23 "700 701" btfloat48cmp - _null_ ));
|
||||||
|
DATA(insert OID = 2195 ( btfloat84cmp PGNSP PGUID 12 f f t f i 2 23 "701 700" btfloat84cmp - _null_ ));
|
||||||
|
|
||||||
|
|
||||||
DATA(insert OID = 2212 ( regprocedurein PGNSP PGUID 12 f f t f s 1 2202 "2275" regprocedurein - _null_ ));
|
DATA(insert OID = 2212 ( regprocedurein PGNSP PGUID 12 f f t f s 1 2202 "2275" regprocedurein - _null_ ));
|
||||||
DESCR("I/O");
|
DESCR("I/O");
|
||||||
|
@ -3157,7 +3164,6 @@ DATA(insert OID = 2273 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16
|
||||||
DESCR("current user privilege on schema by schema oid");
|
DESCR("current user privilege on schema by schema oid");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DATA(insert OID = 2290 ( record_in PGNSP PGUID 12 f f t f i 1 2249 "2275" record_in - _null_ ));
|
DATA(insert OID = 2290 ( record_in PGNSP PGUID 12 f f t f i 1 2249 "2275" record_in - _null_ ));
|
||||||
DESCR("I/O");
|
DESCR("I/O");
|
||||||
DATA(insert OID = 2291 ( record_out PGNSP PGUID 12 f f t f i 1 2275 "2249" record_out - _null_ ));
|
DATA(insert OID = 2291 ( record_out PGNSP PGUID 12 f f t f i 1 2275 "2249" record_out - _null_ ));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: plannodes.h,v 1.69 2003/11/09 21:30:37 tgl Exp $
|
* $Id: plannodes.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -165,6 +165,7 @@ typedef struct IndexScan
|
||||||
List *indxqual; /* list of sublists of index quals */
|
List *indxqual; /* list of sublists of index quals */
|
||||||
List *indxqualorig; /* the same in original form */
|
List *indxqualorig; /* the same in original form */
|
||||||
List *indxstrategy; /* list of sublists of strategy numbers */
|
List *indxstrategy; /* list of sublists of strategy numbers */
|
||||||
|
List *indxsubtype; /* list of sublists of strategy subtypes */
|
||||||
ScanDirection indxorderdir; /* forward or backward or don't care */
|
ScanDirection indxorderdir; /* forward or backward or don't care */
|
||||||
} IndexScan;
|
} IndexScan;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: builtins.h,v 1.228 2003/08/17 19:58:06 tgl Exp $
|
* $Id: builtins.h,v 1.229 2003/11/12 21:15:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -219,6 +219,14 @@ extern Datum btint4cmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btint8cmp(PG_FUNCTION_ARGS);
|
extern Datum btint8cmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btfloat4cmp(PG_FUNCTION_ARGS);
|
extern Datum btfloat4cmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btfloat8cmp(PG_FUNCTION_ARGS);
|
extern Datum btfloat8cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint48cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint84cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint24cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint42cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint28cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btint82cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btfloat48cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum btfloat84cmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btoidcmp(PG_FUNCTION_ARGS);
|
extern Datum btoidcmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btoidvectorcmp(PG_FUNCTION_ARGS);
|
extern Datum btoidvectorcmp(PG_FUNCTION_ARGS);
|
||||||
extern Datum btabstimecmp(PG_FUNCTION_ARGS);
|
extern Datum btabstimecmp(PG_FUNCTION_ARGS);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: geo_decls.h,v 1.41 2003/08/04 02:40:15 momjian Exp $
|
* $Id: geo_decls.h,v 1.42 2003/11/12 21:15:59 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTE
|
* NOTE
|
||||||
* These routines do *not* use the float types from adt/.
|
* These routines do *not* use the float types from adt/.
|
||||||
|
@ -399,7 +399,6 @@ extern Datum circle_area(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_box_union(PG_FUNCTION_ARGS);
|
extern Datum rt_box_union(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_box_inter(PG_FUNCTION_ARGS);
|
extern Datum rt_box_inter(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_box_size(PG_FUNCTION_ARGS);
|
extern Datum rt_box_size(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_bigbox_size(PG_FUNCTION_ARGS);
|
|
||||||
extern Datum rt_poly_size(PG_FUNCTION_ARGS);
|
extern Datum rt_poly_size(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_poly_union(PG_FUNCTION_ARGS);
|
extern Datum rt_poly_union(PG_FUNCTION_ARGS);
|
||||||
extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
|
extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lsyscache.h,v 1.83 2003/11/09 21:30:38 tgl Exp $
|
* $Id: lsyscache.h,v 1.84 2003/11/12 21:15:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -26,10 +26,11 @@ typedef enum IOFuncSelector
|
||||||
|
|
||||||
extern bool op_in_opclass(Oid opno, Oid opclass);
|
extern bool op_in_opclass(Oid opno, Oid opclass);
|
||||||
extern void get_op_opclass_properties(Oid opno, Oid opclass,
|
extern void get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
int *strategy, bool *recheck);
|
int *strategy, Oid *subtype,
|
||||||
extern Oid get_opclass_member(Oid opclass, int16 strategy);
|
bool *recheck);
|
||||||
|
extern Oid get_opclass_member(Oid opclass, Oid subtype, int16 strategy);
|
||||||
extern Oid get_op_hash_function(Oid opno);
|
extern Oid get_op_hash_function(Oid opno);
|
||||||
extern Oid get_opclass_proc(Oid opclass, int16 procnum);
|
extern Oid get_opclass_proc(Oid opclass, Oid subtype, int16 procnum);
|
||||||
extern char *get_attname(Oid relid, AttrNumber attnum);
|
extern char *get_attname(Oid relid, AttrNumber attnum);
|
||||||
extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
|
extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
|
||||||
extern AttrNumber get_attnum(Oid relid, const char *attname);
|
extern AttrNumber get_attnum(Oid relid, const char *attname);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: rel.h,v 1.69 2003/11/09 21:30:38 tgl Exp $
|
* $Id: rel.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -139,8 +139,8 @@ typedef struct RelationData
|
||||||
/*
|
/*
|
||||||
* index access support info (used only for an index relation)
|
* index access support info (used only for an index relation)
|
||||||
*
|
*
|
||||||
* Note: only operators and support procs for the index's own datatype
|
* Note: only default operators and support procs for each opclass are
|
||||||
* are cached, not any cross-type operators. The arrays are indexed by
|
* cached, namely those with subtype zero. The arrays are indexed by
|
||||||
* strategy or support number, which is a sufficient identifier given
|
* strategy or support number, which is a sufficient identifier given
|
||||||
* that restriction.
|
* that restriction.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,7 +47,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
|
||||||
-- in the regression test (we check them using the sequoia 2000
|
-- in the regression test (we check them using the sequoia 2000
|
||||||
-- benchmark).
|
-- benchmark).
|
||||||
--
|
--
|
||||||
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
|
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
|
||||||
-- there's no easy way to check that this command actually is using
|
-- there's no easy way to check that this command actually is using
|
||||||
-- the index, unfortunately. (EXPLAIN would work, but its output
|
-- the index, unfortunately. (EXPLAIN would work, but its output
|
||||||
-- changes too often for me to want to put an EXPLAIN in the test...)
|
-- changes too often for me to want to put an EXPLAIN in the test...)
|
||||||
|
|
|
@ -129,6 +129,14 @@ WHERE amopclaid != 0 AND
|
||||||
------+-----------
|
------+-----------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT ctid, amopsubtype
|
||||||
|
FROM pg_catalog.pg_amop fk
|
||||||
|
WHERE amopsubtype != 0 AND
|
||||||
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
|
||||||
|
ctid | amopsubtype
|
||||||
|
------+-------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
SELECT ctid, amopopr
|
SELECT ctid, amopopr
|
||||||
FROM pg_catalog.pg_amop fk
|
FROM pg_catalog.pg_amop fk
|
||||||
WHERE amopopr != 0 AND
|
WHERE amopopr != 0 AND
|
||||||
|
@ -145,6 +153,14 @@ WHERE amopclaid != 0 AND
|
||||||
------+-----------
|
------+-----------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT ctid, amprocsubtype
|
||||||
|
FROM pg_catalog.pg_amproc fk
|
||||||
|
WHERE amprocsubtype != 0 AND
|
||||||
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
|
||||||
|
ctid | amprocsubtype
|
||||||
|
------+---------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
SELECT ctid, amproc
|
SELECT ctid, amproc
|
||||||
FROM pg_catalog.pg_amproc fk
|
FROM pg_catalog.pg_amproc fk
|
||||||
WHERE amproc != 0 AND
|
WHERE amproc != 0 AND
|
||||||
|
|
|
@ -685,30 +685,61 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
|
||||||
-----------+---------+-----+--------
|
-----------+---------+-----+--------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Detect missing pg_amop entries: should have as many strategy functions
|
-- Detect missing pg_amop entries: should have as many strategy operators
|
||||||
-- as AM expects for each opclass for the AM
|
-- as AM expects for each opclass for the AM. When nondefault subtypes are
|
||||||
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
|
-- present, enforce condition separately for each subtype.
|
||||||
FROM pg_am AS p1, pg_opclass AS p2
|
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
|
||||||
WHERE p2.opcamid = p1.oid AND
|
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
|
||||||
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
|
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
|
||||||
WHERE p3.amopclaid = p2.oid);
|
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
|
||||||
oid | amname | oid | opcname
|
WHERE p4.amopclaid = p2.oid AND
|
||||||
-----+--------+-----+---------
|
p4.amopsubtype = p3.amopsubtype);
|
||||||
|
oid | amname | oid | opcname | amopsubtype
|
||||||
|
-----+--------+-----+---------+-------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Check that amopopr points at a reasonable-looking operator, ie a binary
|
-- Check that amopopr points at a reasonable-looking operator, ie a binary
|
||||||
-- operator yielding boolean.
|
-- operator yielding boolean.
|
||||||
-- NOTE: for 7.1, add restriction that operator inputs are of same type.
|
|
||||||
-- We used to have opclasses like "int24_ops" but these were broken.
|
|
||||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
||||||
FROM pg_amop AS p1, pg_operator AS p2
|
FROM pg_amop AS p1, pg_operator AS p2
|
||||||
WHERE p1.amopopr = p2.oid AND
|
WHERE p1.amopopr = p2.oid AND
|
||||||
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
|
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
|
||||||
p2.oprleft != p2.oprright);
|
|
||||||
amopclaid | amopopr | oid | oprname
|
amopclaid | amopopr | oid | oprname
|
||||||
-----------+---------+-----+---------
|
-----------+---------+-----+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
-- Make a list of all the distinct operator names being used in particular
|
||||||
|
-- strategy slots. This is a bit hokey, since the list might need to change
|
||||||
|
-- in future releases, but it's an effective way of spotting mistakes such as
|
||||||
|
-- swapping two operators within a class.
|
||||||
|
SELECT DISTINCT opcamid, amopstrategy, oprname
|
||||||
|
FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
|
||||||
|
LEFT JOIN pg_operator p3 ON amopopr = p3.oid
|
||||||
|
ORDER BY 1, 2, 3;
|
||||||
|
opcamid | amopstrategy | oprname
|
||||||
|
---------+--------------+---------
|
||||||
|
402 | 1 | <<
|
||||||
|
402 | 2 | &<
|
||||||
|
402 | 3 | &&
|
||||||
|
402 | 4 | &>
|
||||||
|
402 | 5 | >>
|
||||||
|
402 | 6 | ~=
|
||||||
|
402 | 7 | ~
|
||||||
|
402 | 8 | @
|
||||||
|
403 | 1 | <
|
||||||
|
403 | 1 | ~<~
|
||||||
|
403 | 2 | <=
|
||||||
|
403 | 2 | ~<=~
|
||||||
|
403 | 3 | =
|
||||||
|
403 | 3 | ~=~
|
||||||
|
403 | 4 | >=
|
||||||
|
403 | 4 | ~>=~
|
||||||
|
403 | 5 | >
|
||||||
|
403 | 5 | ~>~
|
||||||
|
405 | 1 | =
|
||||||
|
405 | 1 | ~=~
|
||||||
|
(20 rows)
|
||||||
|
|
||||||
-- Check that all operators linked to by opclass entries have selectivity
|
-- Check that all operators linked to by opclass entries have selectivity
|
||||||
-- estimators. This is not absolutely required, but it seems a reasonable
|
-- estimators. This is not absolutely required, but it seems a reasonable
|
||||||
-- thing to insist on for all standard datatypes.
|
-- thing to insist on for all standard datatypes.
|
||||||
|
@ -721,11 +752,31 @@ WHERE p1.amopopr = p2.oid AND
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Check that operator input types match the opclass
|
-- Check that operator input types match the opclass
|
||||||
|
-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
|
||||||
|
-- When amopsubtype is zero (default), oprright must equal oprleft;
|
||||||
|
-- when amopsubtype is not zero, oprright must equal amopsubtype.
|
||||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
(NOT binary_coercible(p3.opcintype, p2.oprleft) OR
|
NOT binary_coercible(p3.opcintype, p2.oprleft);
|
||||||
p2.oprleft != p2.oprright);
|
amopclaid | amopopr | oid | oprname | opcname
|
||||||
|
-----------+---------+-----+---------+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
|
p1.amopsubtype = 0 AND
|
||||||
|
p2.oprleft != p2.oprright;
|
||||||
|
amopclaid | amopopr | oid | oprname | opcname
|
||||||
|
-----------+---------+-----+---------+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
|
p1.amopsubtype != 0 AND
|
||||||
|
p1.amopsubtype != p2.oprright;
|
||||||
amopclaid | amopopr | oid | oprname | opcname
|
amopclaid | amopopr | oid | oprname | opcname
|
||||||
-----------+---------+-----+---------+---------
|
-----------+---------+-----+---------+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
@ -749,14 +800,16 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Detect missing pg_amproc entries: should have as many support functions
|
-- Detect missing pg_amproc entries: should have as many support functions
|
||||||
-- as AM expects for each opclass for the AM
|
-- as AM expects for each opclass for the AM. When nondefault subtypes are
|
||||||
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
|
-- present, enforce condition separately for each subtype.
|
||||||
FROM pg_am AS p1, pg_opclass AS p2
|
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
|
||||||
WHERE p2.opcamid = p1.oid AND
|
FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
|
||||||
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
|
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
|
||||||
WHERE p3.amopclaid = p2.oid);
|
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
|
||||||
oid | amname | oid | opcname
|
WHERE p4.amopclaid = p2.oid AND
|
||||||
-----+--------+-----+---------
|
p4.amprocsubtype = p3.amprocsubtype);
|
||||||
|
oid | amname | oid | opcname | amprocsubtype
|
||||||
|
-----+--------+-----+---------+---------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Unfortunately, we can't check the amproc link very well because the
|
-- Unfortunately, we can't check the amproc link very well because the
|
||||||
|
@ -782,13 +835,15 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- For btree, though, we can do better since we know the support routines
|
-- For btree, though, we can do better since we know the support routines
|
||||||
-- must be of the form cmp(input, input) returns int4.
|
-- must be of the form cmp(input, input) returns int4 in the default case
|
||||||
|
-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
|
||||||
SELECT p1.amopclaid, p1.amprocnum,
|
SELECT p1.amopclaid, p1.amprocnum,
|
||||||
p2.oid, p2.proname,
|
p2.oid, p2.proname,
|
||||||
p3.opcname
|
p3.opcname
|
||||||
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
||||||
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
||||||
|
amprocsubtype = 0 AND
|
||||||
(opckeytype != 0
|
(opckeytype != 0
|
||||||
OR amprocnum != 1
|
OR amprocnum != 1
|
||||||
OR proretset
|
OR proretset
|
||||||
|
@ -800,6 +855,24 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
-----------+-----------+-----+---------+---------
|
-----------+-----------+-----+---------+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT p1.amopclaid, p1.amprocnum,
|
||||||
|
p2.oid, p2.proname,
|
||||||
|
p3.opcname
|
||||||
|
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
||||||
|
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
|
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
||||||
|
amprocsubtype != 0 AND
|
||||||
|
(opckeytype != 0
|
||||||
|
OR amprocnum != 1
|
||||||
|
OR proretset
|
||||||
|
OR prorettype != 23
|
||||||
|
OR pronargs != 2
|
||||||
|
OR NOT binary_coercible(opcintype, proargtypes[0])
|
||||||
|
OR proargtypes[1] != amprocsubtype);
|
||||||
|
amopclaid | amprocnum | oid | proname | opcname
|
||||||
|
-----------+-----------+-----+---------+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
-- For hash we can also do a little better: the support routines must be
|
-- For hash we can also do a little better: the support routines must be
|
||||||
-- of the form hash(something) returns int4. Ideally we'd check that the
|
-- of the form hash(something) returns int4. Ideally we'd check that the
|
||||||
-- opcintype is binary-coercible to the function's input, but there are
|
-- opcintype is binary-coercible to the function's input, but there are
|
||||||
|
|
|
@ -68,7 +68,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
|
||||||
-- in the regression test (we check them using the sequoia 2000
|
-- in the regression test (we check them using the sequoia 2000
|
||||||
-- benchmark).
|
-- benchmark).
|
||||||
--
|
--
|
||||||
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
|
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
|
||||||
|
|
||||||
-- there's no easy way to check that this command actually is using
|
-- there's no easy way to check that this command actually is using
|
||||||
-- the index, unfortunately. (EXPLAIN would work, but its output
|
-- the index, unfortunately. (EXPLAIN would work, but its output
|
||||||
|
|
|
@ -65,6 +65,10 @@ SELECT ctid, amopclaid
|
||||||
FROM pg_catalog.pg_amop fk
|
FROM pg_catalog.pg_amop fk
|
||||||
WHERE amopclaid != 0 AND
|
WHERE amopclaid != 0 AND
|
||||||
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
|
||||||
|
SELECT ctid, amopsubtype
|
||||||
|
FROM pg_catalog.pg_amop fk
|
||||||
|
WHERE amopsubtype != 0 AND
|
||||||
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
|
||||||
SELECT ctid, amopopr
|
SELECT ctid, amopopr
|
||||||
FROM pg_catalog.pg_amop fk
|
FROM pg_catalog.pg_amop fk
|
||||||
WHERE amopopr != 0 AND
|
WHERE amopopr != 0 AND
|
||||||
|
@ -73,6 +77,10 @@ SELECT ctid, amopclaid
|
||||||
FROM pg_catalog.pg_amproc fk
|
FROM pg_catalog.pg_amproc fk
|
||||||
WHERE amopclaid != 0 AND
|
WHERE amopclaid != 0 AND
|
||||||
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
|
||||||
|
SELECT ctid, amprocsubtype
|
||||||
|
FROM pg_catalog.pg_amproc fk
|
||||||
|
WHERE amprocsubtype != 0 AND
|
||||||
|
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
|
||||||
SELECT ctid, amproc
|
SELECT ctid, amproc
|
||||||
FROM pg_catalog.pg_amproc fk
|
FROM pg_catalog.pg_amproc fk
|
||||||
WHERE amproc != 0 AND
|
WHERE amproc != 0 AND
|
||||||
|
|
|
@ -574,25 +574,34 @@ FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3
|
||||||
WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
|
WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
|
||||||
p1.amopstrategy > p2.amstrategies;
|
p1.amopstrategy > p2.amstrategies;
|
||||||
|
|
||||||
-- Detect missing pg_amop entries: should have as many strategy functions
|
-- Detect missing pg_amop entries: should have as many strategy operators
|
||||||
-- as AM expects for each opclass for the AM
|
-- as AM expects for each opclass for the AM. When nondefault subtypes are
|
||||||
|
-- present, enforce condition separately for each subtype.
|
||||||
|
|
||||||
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
|
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
|
||||||
FROM pg_am AS p1, pg_opclass AS p2
|
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
|
||||||
WHERE p2.opcamid = p1.oid AND
|
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
|
||||||
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
|
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
|
||||||
WHERE p3.amopclaid = p2.oid);
|
WHERE p4.amopclaid = p2.oid AND
|
||||||
|
p4.amopsubtype = p3.amopsubtype);
|
||||||
|
|
||||||
-- Check that amopopr points at a reasonable-looking operator, ie a binary
|
-- Check that amopopr points at a reasonable-looking operator, ie a binary
|
||||||
-- operator yielding boolean.
|
-- operator yielding boolean.
|
||||||
-- NOTE: for 7.1, add restriction that operator inputs are of same type.
|
|
||||||
-- We used to have opclasses like "int24_ops" but these were broken.
|
|
||||||
|
|
||||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
||||||
FROM pg_amop AS p1, pg_operator AS p2
|
FROM pg_amop AS p1, pg_operator AS p2
|
||||||
WHERE p1.amopopr = p2.oid AND
|
WHERE p1.amopopr = p2.oid AND
|
||||||
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
|
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
|
||||||
p2.oprleft != p2.oprright);
|
|
||||||
|
-- Make a list of all the distinct operator names being used in particular
|
||||||
|
-- strategy slots. This is a bit hokey, since the list might need to change
|
||||||
|
-- in future releases, but it's an effective way of spotting mistakes such as
|
||||||
|
-- swapping two operators within a class.
|
||||||
|
|
||||||
|
SELECT DISTINCT opcamid, amopstrategy, oprname
|
||||||
|
FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
|
||||||
|
LEFT JOIN pg_operator p3 ON amopopr = p3.oid
|
||||||
|
ORDER BY 1, 2, 3;
|
||||||
|
|
||||||
-- Check that all operators linked to by opclass entries have selectivity
|
-- Check that all operators linked to by opclass entries have selectivity
|
||||||
-- estimators. This is not absolutely required, but it seems a reasonable
|
-- estimators. This is not absolutely required, but it seems a reasonable
|
||||||
|
@ -604,12 +613,26 @@ WHERE p1.amopopr = p2.oid AND
|
||||||
(p2.oprrest = 0 OR p2.oprjoin = 0);
|
(p2.oprrest = 0 OR p2.oprjoin = 0);
|
||||||
|
|
||||||
-- Check that operator input types match the opclass
|
-- Check that operator input types match the opclass
|
||||||
|
-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
|
||||||
|
-- When amopsubtype is zero (default), oprright must equal oprleft;
|
||||||
|
-- when amopsubtype is not zero, oprright must equal amopsubtype.
|
||||||
|
|
||||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
(NOT binary_coercible(p3.opcintype, p2.oprleft) OR
|
NOT binary_coercible(p3.opcintype, p2.oprleft);
|
||||||
p2.oprleft != p2.oprright);
|
|
||||||
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
|
p1.amopsubtype = 0 AND
|
||||||
|
p2.oprleft != p2.oprright;
|
||||||
|
|
||||||
|
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||||
|
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||||
|
WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
|
||||||
|
p1.amopsubtype != 0 AND
|
||||||
|
p1.amopsubtype != p2.oprright;
|
||||||
|
|
||||||
-- **************** pg_amproc ****************
|
-- **************** pg_amproc ****************
|
||||||
|
|
||||||
|
@ -627,13 +650,15 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
|
||||||
p1.amprocnum > p2.amsupport;
|
p1.amprocnum > p2.amsupport;
|
||||||
|
|
||||||
-- Detect missing pg_amproc entries: should have as many support functions
|
-- Detect missing pg_amproc entries: should have as many support functions
|
||||||
-- as AM expects for each opclass for the AM
|
-- as AM expects for each opclass for the AM. When nondefault subtypes are
|
||||||
|
-- present, enforce condition separately for each subtype.
|
||||||
|
|
||||||
SELECT p1.oid, p1.amname, p2.oid, p2.opcname
|
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
|
||||||
FROM pg_am AS p1, pg_opclass AS p2
|
FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
|
||||||
WHERE p2.opcamid = p1.oid AND
|
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
|
||||||
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
|
p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
|
||||||
WHERE p3.amopclaid = p2.oid);
|
WHERE p4.amopclaid = p2.oid AND
|
||||||
|
p4.amprocsubtype = p3.amprocsubtype);
|
||||||
|
|
||||||
-- Unfortunately, we can't check the amproc link very well because the
|
-- Unfortunately, we can't check the amproc link very well because the
|
||||||
-- signature of the function may be different for different support routines
|
-- signature of the function may be different for different support routines
|
||||||
|
@ -656,7 +681,8 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
|
||||||
(p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);
|
(p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);
|
||||||
|
|
||||||
-- For btree, though, we can do better since we know the support routines
|
-- For btree, though, we can do better since we know the support routines
|
||||||
-- must be of the form cmp(input, input) returns int4.
|
-- must be of the form cmp(input, input) returns int4 in the default case
|
||||||
|
-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
|
||||||
|
|
||||||
SELECT p1.amopclaid, p1.amprocnum,
|
SELECT p1.amopclaid, p1.amprocnum,
|
||||||
p2.oid, p2.proname,
|
p2.oid, p2.proname,
|
||||||
|
@ -664,6 +690,7 @@ SELECT p1.amopclaid, p1.amprocnum,
|
||||||
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
||||||
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
||||||
|
amprocsubtype = 0 AND
|
||||||
(opckeytype != 0
|
(opckeytype != 0
|
||||||
OR amprocnum != 1
|
OR amprocnum != 1
|
||||||
OR proretset
|
OR proretset
|
||||||
|
@ -672,6 +699,21 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
OR NOT binary_coercible(opcintype, proargtypes[0])
|
OR NOT binary_coercible(opcintype, proargtypes[0])
|
||||||
OR proargtypes[0] != proargtypes[1]);
|
OR proargtypes[0] != proargtypes[1]);
|
||||||
|
|
||||||
|
SELECT p1.amopclaid, p1.amprocnum,
|
||||||
|
p2.oid, p2.proname,
|
||||||
|
p3.opcname
|
||||||
|
FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
|
||||||
|
WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
|
||||||
|
AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
|
||||||
|
amprocsubtype != 0 AND
|
||||||
|
(opckeytype != 0
|
||||||
|
OR amprocnum != 1
|
||||||
|
OR proretset
|
||||||
|
OR prorettype != 23
|
||||||
|
OR pronargs != 2
|
||||||
|
OR NOT binary_coercible(opcintype, proargtypes[0])
|
||||||
|
OR proargtypes[1] != amprocsubtype);
|
||||||
|
|
||||||
-- For hash we can also do a little better: the support routines must be
|
-- For hash we can also do a little better: the support routines must be
|
||||||
-- of the form hash(something) returns int4. Ideally we'd check that the
|
-- of the form hash(something) returns int4. Ideally we'd check that the
|
||||||
-- opcintype is binary-coercible to the function's input, but there are
|
-- opcintype is binary-coercible to the function's input, but there are
|
||||||
|
|
Loading…
Reference in New Issue