mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Add operator strategy and comparison-value datatype fields to ScanKey.
Remove the 'strategy map' code, which was a large amount of mechanism that no longer had any use except reverse-mapping from procedure OID to strategy number. Passing the strategy number to the index AM in the first place is simpler and faster. This is a preliminary step in planned support for cross-datatype index operations. I'm committing it now since the ScanKeyEntryInitialize() API change touches quite a lot of files, and I want to commit those changes before the tree drifts under me.
This commit is contained in:
parent
723825afeb
commit
c1d62bfd00
@ -1357,8 +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, Anum_pg_index_indrelid,
|
ScanKeyEntryInitialize(&entry, 0,
|
||||||
F_OIDEQ, ObjectIdGetDatum(relid));
|
Anum_pg_index_indrelid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
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,6 +21,7 @@
|
|||||||
#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"
|
||||||
@ -88,8 +89,8 @@ active_listeners(text *relname)
|
|||||||
memcpy(listen_name, VARDATA(relname), len);
|
memcpy(listen_name, VARDATA(relname), len);
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_listener_relname,
|
Anum_pg_listener_relname,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(listen_name));
|
PointerGetDatum(listen_name), NAMEOID);
|
||||||
sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
|
sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.29 2003/08/04 02:39:56 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.30 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -57,12 +57,9 @@ index_keytest(IndexTuple tuple,
|
|||||||
if (key->sk_flags & SK_ISNULL)
|
if (key->sk_flags & SK_ISNULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (key->sk_flags & SK_COMMUTE)
|
|
||||||
test = FunctionCall2(&key->sk_func, key->sk_argument, datum);
|
|
||||||
else
|
|
||||||
test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
|
test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
|
||||||
|
|
||||||
if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE))
|
if (!DatumGetBool(test))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
key++;
|
key++;
|
||||||
|
@ -1,73 +1,46 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* scan.c
|
* scankey.c
|
||||||
* scan direction and key code
|
* scan key support code
|
||||||
*
|
*
|
||||||
* 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
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.22 2003/08/04 02:39:56 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.23 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/skey.h"
|
#include "access/skey.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* ScanKeyEntryIsLegal
|
|
||||||
* True iff the scan key entry is legal.
|
|
||||||
*/
|
|
||||||
#define ScanKeyEntryIsLegal(entry) \
|
|
||||||
( \
|
|
||||||
AssertMacro(PointerIsValid(entry)), \
|
|
||||||
AttributeNumberIsValid((entry)->sk_attno) \
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ScanKeyEntrySetIllegal
|
|
||||||
* Marks a scan key entry as illegal.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ScanKeyEntrySetIllegal(ScanKey entry)
|
|
||||||
{
|
|
||||||
|
|
||||||
Assert(PointerIsValid(entry));
|
|
||||||
|
|
||||||
entry->sk_flags = 0; /* just in case... */
|
|
||||||
entry->sk_attno = InvalidAttrNumber;
|
|
||||||
entry->sk_procedure = 0; /* should be InvalidRegProcedure */
|
|
||||||
entry->sk_func.fn_oid = InvalidOid;
|
|
||||||
entry->sk_argument = (Datum) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ScanKeyEntryInitialize
|
* ScanKeyEntryInitialize
|
||||||
* Initializes a scan key entry.
|
* Initializes a scan key entry given all the field values.
|
||||||
|
* The target procedure is specified by OID.
|
||||||
*
|
*
|
||||||
* Note:
|
* Note: CurrentMemoryContext at call should be as long-lived as the ScanKey
|
||||||
* Assumes the scan key entry is valid.
|
* itself, because that's what will be used for any subsidiary info attached
|
||||||
* Assumes the intialized scan key entry will be legal.
|
* to the ScanKey's FmgrInfo record.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ScanKeyEntryInitialize(ScanKey entry,
|
ScanKeyEntryInitialize(ScanKey entry,
|
||||||
bits16 flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
|
StrategyNumber strategy,
|
||||||
RegProcedure procedure,
|
RegProcedure procedure,
|
||||||
Datum argument)
|
Datum argument,
|
||||||
|
Oid argtype)
|
||||||
{
|
{
|
||||||
Assert(PointerIsValid(entry));
|
|
||||||
|
|
||||||
entry->sk_flags = flags;
|
entry->sk_flags = flags;
|
||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_procedure = procedure;
|
entry->sk_strategy = strategy;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
|
entry->sk_argtype = argtype;
|
||||||
fmgr_info(procedure, &entry->sk_func);
|
fmgr_info(procedure, &entry->sk_func);
|
||||||
|
|
||||||
Assert(ScanKeyEntryIsLegal(entry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -75,25 +48,23 @@ ScanKeyEntryInitialize(ScanKey entry,
|
|||||||
* Initializes a scan key entry using an already-completed FmgrInfo
|
* Initializes a scan key entry using an already-completed FmgrInfo
|
||||||
* function lookup record.
|
* function lookup record.
|
||||||
*
|
*
|
||||||
* mcxt is the memory context holding the scan key; it'll be used for
|
* Note: CurrentMemoryContext at call should be as long-lived as the ScanKey
|
||||||
* any subsidiary info attached to the scankey's FmgrInfo record.
|
* itself, because that's what will be used for any subsidiary info attached
|
||||||
|
* to the ScanKey's FmgrInfo record.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
||||||
bits16 flags,
|
int flags,
|
||||||
AttrNumber attributeNumber,
|
AttrNumber attributeNumber,
|
||||||
|
StrategyNumber strategy,
|
||||||
FmgrInfo *finfo,
|
FmgrInfo *finfo,
|
||||||
MemoryContext mcxt,
|
Datum argument,
|
||||||
Datum argument)
|
Oid argtype)
|
||||||
{
|
{
|
||||||
Assert(PointerIsValid(entry));
|
|
||||||
Assert(RegProcedureIsValid(finfo->fn_oid));
|
|
||||||
|
|
||||||
entry->sk_flags = flags;
|
entry->sk_flags = flags;
|
||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_procedure = finfo->fn_oid;
|
entry->sk_strategy = strategy;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
fmgr_info_copy(&entry->sk_func, finfo, mcxt);
|
entry->sk_argtype = argtype;
|
||||||
|
fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
|
||||||
Assert(ScanKeyEntryIsLegal(entry));
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# Makefile for access/gist
|
# Makefile for access/gist
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.10 2000/08/31 16:09:31 petere Exp $
|
# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ subdir = src/backend/access/gist
|
|||||||
top_builddir = ../../../..
|
top_builddir = ../../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = gist.o gistget.o gistscan.o giststrat.o
|
OBJS = gist.o gistget.o gistscan.o
|
||||||
|
|
||||||
all: SUBSYS.o
|
all: SUBSYS.o
|
||||||
|
|
||||||
|
@ -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.36 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.37 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -249,26 +249,16 @@ gistindex_keytest(IndexTuple tuple,
|
|||||||
IndexTupleSize(tuple) - sizeof(IndexTupleData),
|
IndexTupleSize(tuple) - sizeof(IndexTupleData),
|
||||||
FALSE, isNull);
|
FALSE, isNull);
|
||||||
|
|
||||||
if (key[0].sk_flags & SK_COMMUTE)
|
|
||||||
{
|
|
||||||
test = FunctionCall3(&key[0].sk_func,
|
|
||||||
key[0].sk_argument,
|
|
||||||
PointerGetDatum(&de),
|
|
||||||
ObjectIdGetDatum(key[0].sk_procedure));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
test = FunctionCall3(&key[0].sk_func,
|
test = FunctionCall3(&key[0].sk_func,
|
||||||
PointerGetDatum(&de),
|
PointerGetDatum(&de),
|
||||||
key[0].sk_argument,
|
key[0].sk_argument,
|
||||||
ObjectIdGetDatum(key[0].sk_procedure));
|
Int32GetDatum(key[0].sk_strategy));
|
||||||
}
|
|
||||||
|
|
||||||
if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1))
|
if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1))
|
||||||
if (DatumGetPointer(de.key) != NULL)
|
if (DatumGetPointer(de.key) != NULL)
|
||||||
pfree(DatumGetPointer(de.key));
|
pfree(DatumGetPointer(de.key));
|
||||||
|
|
||||||
if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
|
if (!DatumGetBool(test))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scanKeySize--;
|
scanKeySize--;
|
||||||
|
@ -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.47 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -106,17 +106,13 @@ gistrescan(PG_FUNCTION_ARGS)
|
|||||||
s->numberOfKeys * sizeof(ScanKeyData));
|
s->numberOfKeys * sizeof(ScanKeyData));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Play games here with the scan key to use the Consistent
|
* Modify the scan key so that the Consistent function is called
|
||||||
* function for all comparisons: 1) the sk_procedure field will
|
* for all comparisons. The original operator is passed to the
|
||||||
* now be used to hold the strategy number 2) the sk_func field
|
* Consistent function in the form of its strategy number, which
|
||||||
* will point to the Consistent function
|
* is available from the sk_strategy field.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < s->numberOfKeys; i++)
|
for (i = 0; i < s->numberOfKeys; i++)
|
||||||
{
|
{
|
||||||
s->keyData[i].sk_procedure =
|
|
||||||
RelationGetGISTStrategy(s->indexRelation,
|
|
||||||
s->keyData[i].sk_attno,
|
|
||||||
s->keyData[i].sk_procedure);
|
|
||||||
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
|
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* giststrat.c
|
|
||||||
* strategy map data for GiSTs.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "access/gist.h"
|
|
||||||
#include "access/istrat.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: negate, commute, and negatecommute all assume that operators are
|
|
||||||
* ordered as follows in the strategy map:
|
|
||||||
*
|
|
||||||
* contains, contained-by
|
|
||||||
*
|
|
||||||
* The negate, commute, and negatecommute arrays are used by the planner
|
|
||||||
* to plan indexed scans over data that appears in the qualificiation in
|
|
||||||
* a boolean negation, or whose operands appear in the wrong order. For
|
|
||||||
* example, if the operator "<%" means "contains", and the user says
|
|
||||||
*
|
|
||||||
* where not rel.box <% "(10,10,20,20)"::box
|
|
||||||
*
|
|
||||||
* the planner can plan an index scan by noting that GiST indices have
|
|
||||||
* an operator in their operator class for negating <%.
|
|
||||||
*
|
|
||||||
* Similarly, if the user says something like
|
|
||||||
*
|
|
||||||
* where "(10,10,20,20)"::box <% rel.box
|
|
||||||
*
|
|
||||||
* the planner can see that the GiST index on rel.box has an operator in
|
|
||||||
* its opclass for commuting <%, and plan the scan using that operator.
|
|
||||||
* This added complexity in the access methods makes the planner a lot easier
|
|
||||||
* to write.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* if a op b, what operator tells us if (not a op b)? */
|
|
||||||
static StrategyNumber GISTNegate[GISTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
|
|
||||||
static StrategyNumber GISTCommute[GISTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
|
|
||||||
static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GiSTs do not currently support TermData (see rtree/rtstrat.c for
|
|
||||||
* discussion of
|
|
||||||
* TermData) -- such logic must be encoded in the user's Consistent function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static StrategyExpression GISTEvaluationExpressions[GISTNStrategies] = {
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If you were sufficiently attentive to detail, you would go through
|
|
||||||
* the ExpressionData pain above for every one of the strategies
|
|
||||||
* we defined. I am not. Now we declare the StrategyEvaluationData
|
|
||||||
* structure that gets shipped around to help the planner and the access
|
|
||||||
* method decide what sort of scan it should do, based on (a) what the
|
|
||||||
* user asked for, (b) what operators are defined for a particular opclass,
|
|
||||||
* and (c) the reams of information we supplied above.
|
|
||||||
*
|
|
||||||
* The idea of all of this initialized data is to make life easier on the
|
|
||||||
* user when he defines a new operator class to use this access method.
|
|
||||||
* By filling in all the data, we let him get away with leaving holes in his
|
|
||||||
* operator class, and still let him use the index. The added complexity
|
|
||||||
* in the access methods just isn't worth the trouble, though.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static StrategyEvaluationData GISTEvaluationData = {
|
|
||||||
GISTNStrategies, /* # of strategies */
|
|
||||||
(StrategyTransformMap) GISTNegate, /* how to do (not qual) */
|
|
||||||
(StrategyTransformMap) GISTCommute, /* how to swap operands */
|
|
||||||
(StrategyTransformMap) GISTNegateCommute, /* how to do both */
|
|
||||||
GISTEvaluationExpressions
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
StrategyNumber
|
|
||||||
RelationGetGISTStrategy(Relation r,
|
|
||||||
AttrNumber attnum,
|
|
||||||
RegProcedure proc)
|
|
||||||
{
|
|
||||||
return RelationGetStrategy(r, attnum, &GISTEvaluationData, proc);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
bool
|
|
||||||
RelationInvokeGISTStrategy(Relation r,
|
|
||||||
AttrNumber attnum,
|
|
||||||
StrategyNumber s,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
|
|
||||||
left, right));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -4,7 +4,7 @@
|
|||||||
# Makefile for access/hash
|
# Makefile for access/hash
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.10 2000/08/31 16:09:33 petere Exp $
|
# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ top_builddir = ../../../..
|
|||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \
|
OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \
|
||||||
hashsearch.o hashstrat.o hashutil.o
|
hashsearch.o hashutil.o
|
||||||
|
|
||||||
all: SUBSYS.o
|
all: SUBSYS.o
|
||||||
|
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* hashstrat.c
|
|
||||||
* Strategy map entries for the hash indexed access method
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.23 2003/08/04 02:39:57 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "access/hash.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* only one valid strategy for hash tables: equality.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
|
|
||||||
static StrategyNumber HTNegate[HTMaxStrategyNumber] = {
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyNumber HTCommute[HTMaxStrategyNumber] = {
|
|
||||||
HTEqualStrategyNumber
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyNumber HTNegateCommute[HTMaxStrategyNumber] = {
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyExpression HTEvaluationExpressions[HTMaxStrategyNumber] = {
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyEvaluationData HTEvaluationData = {
|
|
||||||
HTMaxStrategyNumber,
|
|
||||||
(StrategyTransformMap) HTNegate,
|
|
||||||
(StrategyTransformMap) HTCommute,
|
|
||||||
(StrategyTransformMap) HTNegateCommute,
|
|
||||||
HTEvaluationExpressions
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
|
||||||
* RelationGetHashStrategy
|
|
||||||
* ----------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
static StrategyNumber
|
|
||||||
_hash_getstrat(Relation rel,
|
|
||||||
AttrNumber attno,
|
|
||||||
RegProcedure proc)
|
|
||||||
{
|
|
||||||
StrategyNumber strat;
|
|
||||||
|
|
||||||
strat = RelationGetStrategy(rel, attno, &HTEvaluationData, proc);
|
|
||||||
|
|
||||||
Assert(StrategyNumberIsValid(strat));
|
|
||||||
|
|
||||||
return strat;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
static bool
|
|
||||||
_hash_invokestrat(Relation rel,
|
|
||||||
AttrNumber attno,
|
|
||||||
StrategyNumber strat,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
|
|
||||||
left, right));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.38 2003/08/04 23:59:37 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.39 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#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"
|
||||||
@ -967,11 +968,11 @@ 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,
|
ScanKeyEntryInitialize(&toastkey, 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
(RegProcedure) 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
|
||||||
@ -1039,11 +1040,11 @@ 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,
|
ScanKeyEntryInitialize(&toastkey, 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
(RegProcedure) 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
|
||||||
@ -1194,37 +1195,33 @@ 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],
|
ScanKeyEntryInitialize(&toastkey[0], 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 1,
|
(AttrNumber) 1,
|
||||||
(RegProcedure) F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now dependent on number of chunks:
|
* Use equality condition for one chunk, a range condition otherwise:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (numchunks == 1)
|
if (numchunks == 1)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&toastkey[1],
|
ScanKeyEntryInitialize(&toastkey[1], 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
(RegProcedure) F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(startchunk));
|
Int32GetDatum(startchunk), INT4OID);
|
||||||
nscankeys = 2;
|
nscankeys = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&toastkey[1],
|
ScanKeyEntryInitialize(&toastkey[1], 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
(RegProcedure) F_INT4GE,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
Int32GetDatum(startchunk));
|
Int32GetDatum(startchunk), INT4OID);
|
||||||
ScanKeyEntryInitialize(&toastkey[2],
|
ScanKeyEntryInitialize(&toastkey[2], 0,
|
||||||
(bits16) 0,
|
|
||||||
(AttrNumber) 2,
|
(AttrNumber) 2,
|
||||||
(RegProcedure) F_INT4LE,
|
BTLessEqualStrategyNumber, F_INT4LE,
|
||||||
Int32GetDatum(endchunk));
|
Int32GetDatum(endchunk), INT4OID);
|
||||||
nscankeys = 3;
|
nscankeys = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# Makefile for access/index
|
# Makefile for access/index
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.10 2000/08/31 16:09:36 petere Exp $
|
# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ subdir = src/backend/access/index
|
|||||||
top_builddir = ../../../..
|
top_builddir = ../../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = genam.o indexam.o istrat.o
|
OBJS = genam.o indexam.o
|
||||||
|
|
||||||
all: SUBSYS.o
|
all: SUBSYS.o
|
||||||
|
|
||||||
|
@ -1,479 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* istrat.c
|
|
||||||
* index scan strategy manipulation code and index strategy manipulation
|
|
||||||
* operator code.
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.60 2003/08/04 02:39:57 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "access/istrat.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_ASSERT_CHECKING
|
|
||||||
static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
|
|
||||||
static bool StrategyExpressionIsValid(StrategyExpression expression,
|
|
||||||
StrategyNumber maxStrategy);
|
|
||||||
static bool StrategyOperatorIsValid(StrategyOperator operator,
|
|
||||||
StrategyNumber maxStrategy);
|
|
||||||
static bool StrategyTermIsValid(StrategyTerm term,
|
|
||||||
StrategyNumber maxStrategy);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
|
||||||
* misc strategy support routines
|
|
||||||
* ----------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyNumberIsValid
|
|
||||||
* StrategyNumberIsInBounds
|
|
||||||
* StrategyMapIsValid
|
|
||||||
* StrategyTransformMapIsValid
|
|
||||||
* IndexStrategyIsValid
|
|
||||||
*
|
|
||||||
* ... are now macros in istrat.h -cim 4/27/91
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyMapGetScanKeyEntry
|
|
||||||
* Returns a scan key entry of a index strategy mapping member.
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Assumes that the index strategy mapping is valid.
|
|
||||||
* Assumes that the index strategy number is valid.
|
|
||||||
* Bounds checking should be done outside this routine.
|
|
||||||
*/
|
|
||||||
ScanKey
|
|
||||||
StrategyMapGetScanKeyEntry(StrategyMap map,
|
|
||||||
StrategyNumber strategyNumber)
|
|
||||||
{
|
|
||||||
Assert(StrategyMapIsValid(map));
|
|
||||||
Assert(StrategyNumberIsValid(strategyNumber));
|
|
||||||
return &map->entry[strategyNumber - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IndexStrategyGetStrategyMap
|
|
||||||
* Returns an index strategy mapping of an index strategy.
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Assumes that the index strategy is valid.
|
|
||||||
* Assumes that the number of index strategies is valid.
|
|
||||||
* Bounds checking should be done outside this routine.
|
|
||||||
*/
|
|
||||||
StrategyMap
|
|
||||||
IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
|
|
||||||
StrategyNumber maxStrategyNum,
|
|
||||||
AttrNumber attrNum)
|
|
||||||
{
|
|
||||||
Assert(IndexStrategyIsValid(indexStrategy));
|
|
||||||
Assert(StrategyNumberIsValid(maxStrategyNum));
|
|
||||||
Assert(AttributeNumberIsValid(attrNum));
|
|
||||||
|
|
||||||
maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */
|
|
||||||
return &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AttributeNumberGetIndexStrategySize
|
|
||||||
* Computes the size of an index strategy.
|
|
||||||
*/
|
|
||||||
Size
|
|
||||||
AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
|
|
||||||
StrategyNumber maxStrategyNumber)
|
|
||||||
{
|
|
||||||
maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
|
|
||||||
return maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ASSERT_CHECKING
|
|
||||||
/*
|
|
||||||
* StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* StrategyOperatorIsValid
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
StrategyOperatorIsValid(StrategyOperator operator,
|
|
||||||
StrategyNumber maxStrategy)
|
|
||||||
{
|
|
||||||
return (bool)
|
|
||||||
(PointerIsValid(operator) &&
|
|
||||||
StrategyNumberIsInBounds(operator->strategy, maxStrategy) &&
|
|
||||||
!(operator->flags & ~(SK_NEGATE | SK_COMMUTE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* StrategyTermIsValid
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
StrategyTermIsValid(StrategyTerm term,
|
|
||||||
StrategyNumber maxStrategy)
|
|
||||||
{
|
|
||||||
Index index;
|
|
||||||
|
|
||||||
if (!PointerIsValid(term) || term->degree == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (index = 0; index < term->degree; index += 1)
|
|
||||||
{
|
|
||||||
if (!StrategyOperatorIsValid(&term->operatorData[index],
|
|
||||||
maxStrategy))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* StrategyExpressionIsValid
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
StrategyExpressionIsValid(StrategyExpression expression,
|
|
||||||
StrategyNumber maxStrategy)
|
|
||||||
{
|
|
||||||
StrategyTerm *termP;
|
|
||||||
|
|
||||||
if (!PointerIsValid(expression))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!StrategyTermIsValid(expression->term[0], maxStrategy))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
termP = &expression->term[1];
|
|
||||||
while (StrategyTermIsValid(*termP, maxStrategy))
|
|
||||||
termP += 1;
|
|
||||||
|
|
||||||
return (bool)
|
|
||||||
(!PointerIsValid(*termP));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* StrategyEvaluationIsValid
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
StrategyEvaluationIsValid(StrategyEvaluation evaluation)
|
|
||||||
{
|
|
||||||
Index index;
|
|
||||||
|
|
||||||
if (!PointerIsValid(evaluation) ||
|
|
||||||
!StrategyNumberIsValid(evaluation->maxStrategy) ||
|
|
||||||
!StrategyTransformMapIsValid(evaluation->negateTransform) ||
|
|
||||||
!StrategyTransformMapIsValid(evaluation->commuteTransform) ||
|
|
||||||
!StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (index = 0; index < evaluation->maxStrategy; index += 1)
|
|
||||||
{
|
|
||||||
if (!StrategyExpressionIsValid(evaluation->expression[index],
|
|
||||||
evaluation->maxStrategy))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/* ----------------
|
|
||||||
* StrategyTermEvaluate
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
StrategyTermEvaluate(StrategyTerm term,
|
|
||||||
StrategyMap map,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
Index index;
|
|
||||||
StrategyOperator operator;
|
|
||||||
|
|
||||||
for (index = 0, operator = &term->operatorData[0];
|
|
||||||
index < term->degree; index += 1, operator += 1)
|
|
||||||
{
|
|
||||||
ScanKey entry;
|
|
||||||
|
|
||||||
entry = &map->entry[operator->strategy - 1];
|
|
||||||
|
|
||||||
Assert(RegProcedureIsValid(entry->sk_procedure));
|
|
||||||
|
|
||||||
switch (operator->flags ^ entry->sk_flags)
|
|
||||||
{
|
|
||||||
case 0x0:
|
|
||||||
result = DatumGetBool(FunctionCall2(&entry->sk_func,
|
|
||||||
left, right));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SK_NEGATE:
|
|
||||||
result = !DatumGetBool(FunctionCall2(&entry->sk_func,
|
|
||||||
left, right));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SK_COMMUTE:
|
|
||||||
result = DatumGetBool(FunctionCall2(&entry->sk_func,
|
|
||||||
right, left));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SK_NEGATE | SK_COMMUTE:
|
|
||||||
result = !DatumGetBool(FunctionCall2(&entry->sk_func,
|
|
||||||
right, left));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
elog(ERROR, "impossible strategy case: %d",
|
|
||||||
operator->flags ^ entry->sk_flags);
|
|
||||||
}
|
|
||||||
if (!result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* RelationGetStrategy
|
|
||||||
*
|
|
||||||
* Identify strategy number that describes given procedure, if there is one.
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
StrategyNumber
|
|
||||||
RelationGetStrategy(Relation relation,
|
|
||||||
AttrNumber attributeNumber,
|
|
||||||
StrategyEvaluation evaluation,
|
|
||||||
RegProcedure procedure)
|
|
||||||
{
|
|
||||||
StrategyNumber strategy;
|
|
||||||
StrategyMap strategyMap;
|
|
||||||
ScanKey entry;
|
|
||||||
Index index;
|
|
||||||
int numattrs;
|
|
||||||
|
|
||||||
Assert(RelationIsValid(relation));
|
|
||||||
numattrs = RelationGetNumberOfAttributes(relation);
|
|
||||||
|
|
||||||
Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
|
|
||||||
Assert((attributeNumber >= 1) && (attributeNumber <= numattrs));
|
|
||||||
|
|
||||||
Assert(StrategyEvaluationIsValid(evaluation));
|
|
||||||
Assert(RegProcedureIsValid(procedure));
|
|
||||||
|
|
||||||
strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
|
|
||||||
evaluation->maxStrategy,
|
|
||||||
attributeNumber);
|
|
||||||
|
|
||||||
/* get a strategy number for the procedure ignoring flags for now */
|
|
||||||
for (index = 0; index < evaluation->maxStrategy; index += 1)
|
|
||||||
{
|
|
||||||
if (strategyMap->entry[index].sk_procedure == procedure)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == evaluation->maxStrategy)
|
|
||||||
return InvalidStrategy;
|
|
||||||
|
|
||||||
strategy = 1 + index;
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
|
|
||||||
|
|
||||||
Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE)));
|
|
||||||
|
|
||||||
switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE))
|
|
||||||
{
|
|
||||||
case 0x0:
|
|
||||||
return strategy;
|
|
||||||
|
|
||||||
case SK_NEGATE:
|
|
||||||
strategy = evaluation->negateTransform->strategy[strategy - 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SK_COMMUTE:
|
|
||||||
strategy = evaluation->commuteTransform->strategy[strategy - 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SK_NEGATE | SK_COMMUTE:
|
|
||||||
strategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
elog(ERROR, "impossible strategy case: %d",
|
|
||||||
entry->sk_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
|
|
||||||
{
|
|
||||||
if (!StrategyNumberIsValid(strategy))
|
|
||||||
elog(ERROR, "corrupted strategy evaluation");
|
|
||||||
}
|
|
||||||
|
|
||||||
return strategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/* ----------------
|
|
||||||
* RelationInvokeStrategy
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
bool /* XXX someday, this may return Datum */
|
|
||||||
RelationInvokeStrategy(Relation relation,
|
|
||||||
StrategyEvaluation evaluation,
|
|
||||||
AttrNumber attributeNumber,
|
|
||||||
StrategyNumber strategy,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
StrategyNumber newStrategy;
|
|
||||||
StrategyMap strategyMap;
|
|
||||||
ScanKey entry;
|
|
||||||
StrategyTermData termData;
|
|
||||||
int numattrs;
|
|
||||||
|
|
||||||
Assert(RelationIsValid(relation));
|
|
||||||
Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
|
|
||||||
numattrs = RelationGetNumberOfAttributes(relation);
|
|
||||||
|
|
||||||
Assert(StrategyEvaluationIsValid(evaluation));
|
|
||||||
Assert(AttributeNumberIsValid(attributeNumber));
|
|
||||||
Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
|
|
||||||
|
|
||||||
Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy));
|
|
||||||
|
|
||||||
termData.degree = 1;
|
|
||||||
|
|
||||||
strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
|
|
||||||
evaluation->maxStrategy,
|
|
||||||
attributeNumber);
|
|
||||||
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
|
|
||||||
|
|
||||||
if (RegProcedureIsValid(entry->sk_procedure))
|
|
||||||
{
|
|
||||||
termData.operatorData[0].strategy = strategy;
|
|
||||||
termData.operatorData[0].flags = 0x0;
|
|
||||||
|
|
||||||
return StrategyTermEvaluate(&termData, strategyMap, left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
newStrategy = evaluation->negateTransform->strategy[strategy - 1];
|
|
||||||
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
|
|
||||||
{
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
|
|
||||||
|
|
||||||
if (RegProcedureIsValid(entry->sk_procedure))
|
|
||||||
{
|
|
||||||
termData.operatorData[0].strategy = newStrategy;
|
|
||||||
termData.operatorData[0].flags = SK_NEGATE;
|
|
||||||
|
|
||||||
return StrategyTermEvaluate(&termData, strategyMap, left, right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
|
|
||||||
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
|
|
||||||
{
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
|
|
||||||
|
|
||||||
if (RegProcedureIsValid(entry->sk_procedure))
|
|
||||||
{
|
|
||||||
termData.operatorData[0].strategy = newStrategy;
|
|
||||||
termData.operatorData[0].flags = SK_COMMUTE;
|
|
||||||
|
|
||||||
return StrategyTermEvaluate(&termData, strategyMap, left, right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
|
|
||||||
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
|
|
||||||
{
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
|
|
||||||
|
|
||||||
if (RegProcedureIsValid(entry->sk_procedure))
|
|
||||||
{
|
|
||||||
termData.operatorData[0].strategy = newStrategy;
|
|
||||||
termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE;
|
|
||||||
|
|
||||||
return StrategyTermEvaluate(&termData, strategyMap, left, right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PointerIsValid(evaluation->expression[strategy - 1]))
|
|
||||||
{
|
|
||||||
StrategyTerm *termP;
|
|
||||||
|
|
||||||
termP = &evaluation->expression[strategy - 1]->term[0];
|
|
||||||
while (PointerIsValid(*termP))
|
|
||||||
{
|
|
||||||
Index index;
|
|
||||||
|
|
||||||
for (index = 0; index < (*termP)->degree; index += 1)
|
|
||||||
{
|
|
||||||
entry = StrategyMapGetScanKeyEntry(strategyMap,
|
|
||||||
(*termP)->operatorData[index].strategy);
|
|
||||||
|
|
||||||
if (!RegProcedureIsValid(entry->sk_procedure))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == (*termP)->degree)
|
|
||||||
return StrategyTermEvaluate(*termP, strategyMap, left, right);
|
|
||||||
|
|
||||||
termP += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elog(ERROR, "cannot evaluate strategy %d", strategy);
|
|
||||||
|
|
||||||
/* not reached, just to make compiler happy */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* IndexStrategyDisplay
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#ifdef ISTRATDEBUG
|
|
||||||
int
|
|
||||||
IndexStrategyDisplay(IndexStrategy indexStrategy,
|
|
||||||
StrategyNumber numberOfStrategies,
|
|
||||||
int numberOfAttributes)
|
|
||||||
{
|
|
||||||
StrategyMap strategyMap;
|
|
||||||
AttrNumber attributeNumber;
|
|
||||||
StrategyNumber strategyNumber;
|
|
||||||
|
|
||||||
for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
|
|
||||||
attributeNumber += 1)
|
|
||||||
{
|
|
||||||
strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
|
|
||||||
numberOfStrategies,
|
|
||||||
attributeNumber);
|
|
||||||
|
|
||||||
for (strategyNumber = 1;
|
|
||||||
strategyNumber <= AMStrategies(numberOfStrategies);
|
|
||||||
strategyNumber += 1)
|
|
||||||
{
|
|
||||||
printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
|
|
||||||
attributeNumber, strategyNumber,
|
|
||||||
strategyMap->entry[strategyNumber - 1].sk_procedure,
|
|
||||||
strategyMap->entry[strategyNumber - 1].sk_procedure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(ISTRATDEBUG) */
|
|
@ -4,7 +4,7 @@
|
|||||||
# Makefile for access/nbtree
|
# Makefile for access/nbtree
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.12 2003/02/21 00:06:21 tgl Exp $
|
# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.13 2003/11/09 21:30:35 tgl Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ top_builddir = ../../../..
|
|||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \
|
OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \
|
||||||
nbtstrat.o nbtutils.o nbtsort.o nbtxlog.o
|
nbtutils.o nbtsort.o nbtxlog.o
|
||||||
|
|
||||||
all: SUBSYS.o
|
all: SUBSYS.o
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* btinsert.c
|
* nbtinsert.c
|
||||||
* Item insertion in Lehman and Yao btrees for Postgres.
|
* Item insertion in Lehman and Yao btrees for Postgres.
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.106 2003/09/25 06:57:57 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.107 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -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.80 2003/08/08 21:41:27 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.81 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -488,8 +488,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
/* if we didn't find a boundary for the preceding attr, quit */
|
/* if we didn't find a boundary for the preceding attr, quit */
|
||||||
if (attno > keysCount + 1)
|
if (attno > keysCount + 1)
|
||||||
break;
|
break;
|
||||||
strat = _bt_getstrat(rel, attno,
|
|
||||||
so->keyData[i].sk_procedure);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can we use this key as a starting boundary for this attr?
|
* Can we use this key as a starting boundary for this attr?
|
||||||
@ -497,6 +495,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
* We can use multiple keys if they look like, say, = >= = but we
|
* We can use multiple keys if they look like, say, = >= = but we
|
||||||
* have to stop after accepting a > or < boundary.
|
* have to stop after accepting a > or < boundary.
|
||||||
*/
|
*/
|
||||||
|
strat = so->keyData[i].sk_strategy;
|
||||||
if (strat == strat_total ||
|
if (strat == strat_total ||
|
||||||
strat == BTEqualStrategyNumber)
|
strat == BTEqualStrategyNumber)
|
||||||
nKeyIs[keysCount++] = i;
|
nKeyIs[keysCount++] = i;
|
||||||
@ -555,13 +554,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
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?
|
||||||
|
*/
|
||||||
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,
|
so->keyData[j].sk_flags,
|
||||||
i + 1,
|
i + 1,
|
||||||
|
InvalidStrategy,
|
||||||
procinfo,
|
procinfo,
|
||||||
CurrentMemoryContext,
|
so->keyData[j].sk_argument,
|
||||||
so->keyData[j].sk_argument);
|
so->keyData[j].sk_argtype);
|
||||||
}
|
}
|
||||||
if (nKeyIs)
|
if (nKeyIs)
|
||||||
pfree(nKeyIs);
|
pfree(nKeyIs);
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* nbtstrat.c
|
|
||||||
* Strategy map entries for the btree indexed access method
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.18 2003/08/04 02:39:57 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "access/istrat.h"
|
|
||||||
#include "access/nbtree.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note:
|
|
||||||
* StrategyNegate, StrategyCommute, and StrategyNegateCommute
|
|
||||||
* assume <, <=, ==, >=, > ordering.
|
|
||||||
*/
|
|
||||||
static StrategyNumber BTNegate[BTMaxStrategyNumber] = {
|
|
||||||
BTGreaterEqualStrategyNumber,
|
|
||||||
BTGreaterStrategyNumber,
|
|
||||||
InvalidStrategy,
|
|
||||||
BTLessStrategyNumber,
|
|
||||||
BTLessEqualStrategyNumber
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyNumber BTCommute[BTMaxStrategyNumber] = {
|
|
||||||
BTGreaterStrategyNumber,
|
|
||||||
BTGreaterEqualStrategyNumber,
|
|
||||||
InvalidStrategy,
|
|
||||||
BTLessEqualStrategyNumber,
|
|
||||||
BTLessStrategyNumber
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyNumber BTNegateCommute[BTMaxStrategyNumber] = {
|
|
||||||
BTLessEqualStrategyNumber,
|
|
||||||
BTLessStrategyNumber,
|
|
||||||
InvalidStrategy,
|
|
||||||
BTGreaterStrategyNumber,
|
|
||||||
BTGreaterEqualStrategyNumber
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16 BTLessTermData[] = { /* XXX type clash */
|
|
||||||
2,
|
|
||||||
BTLessStrategyNumber,
|
|
||||||
SK_NEGATE,
|
|
||||||
BTLessStrategyNumber,
|
|
||||||
SK_NEGATE | SK_COMMUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16 BTLessEqualTermData[] = { /* XXX type clash */
|
|
||||||
2,
|
|
||||||
BTLessEqualStrategyNumber,
|
|
||||||
0x0,
|
|
||||||
BTLessEqualStrategyNumber,
|
|
||||||
SK_COMMUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16 BTGreaterEqualTermData[] = { /* XXX type clash */
|
|
||||||
2,
|
|
||||||
BTGreaterEqualStrategyNumber,
|
|
||||||
0x0,
|
|
||||||
BTGreaterEqualStrategyNumber,
|
|
||||||
SK_COMMUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16 BTGreaterTermData[] = { /* XXX type clash */
|
|
||||||
2,
|
|
||||||
BTGreaterStrategyNumber,
|
|
||||||
SK_NEGATE,
|
|
||||||
BTGreaterStrategyNumber,
|
|
||||||
SK_NEGATE | SK_COMMUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyTerm BTEqualExpressionData[] = {
|
|
||||||
(StrategyTerm) BTLessTermData, /* XXX */
|
|
||||||
(StrategyTerm) BTLessEqualTermData, /* XXX */
|
|
||||||
(StrategyTerm) BTGreaterEqualTermData, /* XXX */
|
|
||||||
(StrategyTerm) BTGreaterTermData, /* XXX */
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyExpression BTEvaluationExpressions[BTMaxStrategyNumber] = {
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
(StrategyExpression) BTEqualExpressionData,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyEvaluationData BTEvaluationData = {
|
|
||||||
BTMaxStrategyNumber,
|
|
||||||
(StrategyTransformMap) BTNegate,
|
|
||||||
(StrategyTransformMap) BTCommute,
|
|
||||||
(StrategyTransformMap) BTNegateCommute,
|
|
||||||
BTEvaluationExpressions
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
|
||||||
* RelationGetBTStrategy
|
|
||||||
* ----------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
StrategyNumber
|
|
||||||
_bt_getstrat(Relation rel,
|
|
||||||
AttrNumber attno,
|
|
||||||
RegProcedure proc)
|
|
||||||
{
|
|
||||||
StrategyNumber strat;
|
|
||||||
|
|
||||||
strat = RelationGetStrategy(rel, attno, &BTEvaluationData, proc);
|
|
||||||
|
|
||||||
Assert(StrategyNumberIsValid(strat));
|
|
||||||
|
|
||||||
return strat;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
|
|
||||||
bool
|
|
||||||
_bt_invokestrat(Relation rel,
|
|
||||||
AttrNumber attno,
|
|
||||||
StrategyNumber strat,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat,
|
|
||||||
left, right));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* btutils.c
|
* nbtutils.c
|
||||||
* Utility code for Postgres btree implementation.
|
* Utility code for Postgres btree implementation.
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.54 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.55 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,13 +16,10 @@
|
|||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/istrat.h"
|
|
||||||
#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"
|
||||||
|
|
||||||
static int _bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -39,10 +36,6 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
|||||||
TupleDesc itupdesc;
|
TupleDesc itupdesc;
|
||||||
int natts;
|
int natts;
|
||||||
int i;
|
int i;
|
||||||
FmgrInfo *procinfo;
|
|
||||||
Datum arg;
|
|
||||||
bool null;
|
|
||||||
bits16 flag;
|
|
||||||
|
|
||||||
itupdesc = RelationGetDescr(rel);
|
itupdesc = RelationGetDescr(rel);
|
||||||
natts = RelationGetNumberOfAttributes(rel);
|
natts = RelationGetNumberOfAttributes(rel);
|
||||||
@ -51,15 +44,23 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
|||||||
|
|
||||||
for (i = 0; i < natts; i++)
|
for (i = 0; i < natts; i++)
|
||||||
{
|
{
|
||||||
|
FmgrInfo *procinfo;
|
||||||
|
Datum arg;
|
||||||
|
bool null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can use the cached support procs since no cross-type 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);
|
||||||
flag = null ? SK_ISNULL : 0x0;
|
|
||||||
ScanKeyEntryInitializeWithInfo(&skey[i],
|
ScanKeyEntryInitializeWithInfo(&skey[i],
|
||||||
flag,
|
null ? SK_ISNULL : 0,
|
||||||
(AttrNumber) (i + 1),
|
(AttrNumber) (i + 1),
|
||||||
|
InvalidStrategy,
|
||||||
procinfo,
|
procinfo,
|
||||||
CurrentMemoryContext,
|
arg,
|
||||||
arg);
|
itupdesc->attrs[i]->atttypid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return skey;
|
return skey;
|
||||||
@ -68,33 +69,42 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
|||||||
/*
|
/*
|
||||||
* _bt_mkscankey_nodata
|
* _bt_mkscankey_nodata
|
||||||
* Build a scan key that contains comparator routines appropriate to
|
* Build a scan key that contains comparator routines appropriate to
|
||||||
* the key datatypes, but no comparison data.
|
* the key datatypes, but no comparison data. The comparison data
|
||||||
|
* ultimately used must match the key datatypes.
|
||||||
*
|
*
|
||||||
* The result cannot be used with _bt_compare(). Currently this
|
* The result cannot be used with _bt_compare(). Currently this
|
||||||
* routine is only called by utils/sort/tuplesort.c, which has its
|
* routine is only called by nbtsort.c and tuplesort.c, which have
|
||||||
* own comparison routine.
|
* their own comparison routines.
|
||||||
*/
|
*/
|
||||||
ScanKey
|
ScanKey
|
||||||
_bt_mkscankey_nodata(Relation rel)
|
_bt_mkscankey_nodata(Relation rel)
|
||||||
{
|
{
|
||||||
ScanKey skey;
|
ScanKey skey;
|
||||||
|
TupleDesc itupdesc;
|
||||||
int natts;
|
int natts;
|
||||||
int i;
|
int i;
|
||||||
FmgrInfo *procinfo;
|
|
||||||
|
|
||||||
|
itupdesc = RelationGetDescr(rel);
|
||||||
natts = RelationGetNumberOfAttributes(rel);
|
natts = RelationGetNumberOfAttributes(rel);
|
||||||
|
|
||||||
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
|
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
|
||||||
|
|
||||||
for (i = 0; i < natts; i++)
|
for (i = 0; i < natts; i++)
|
||||||
{
|
{
|
||||||
|
FmgrInfo *procinfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can use the cached support procs since no cross-type 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,
|
||||||
procinfo,
|
procinfo,
|
||||||
CurrentMemoryContext,
|
(Datum) 0,
|
||||||
(Datum) 0);
|
itupdesc->attrs[i]->atttypid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return skey;
|
return skey;
|
||||||
@ -185,17 +195,6 @@ _bt_formitem(IndexTuple itup)
|
|||||||
* The initial ordering of the keys is expected to be by attribute already
|
* 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
|
* (see group_clauses_by_indexkey() in indxpath.c). The task here is to
|
||||||
* standardize the appearance of multiple keys for the same attribute.
|
* standardize the appearance of multiple keys for the same attribute.
|
||||||
*
|
|
||||||
* XXX this routine is one of many places that fail to handle SK_COMMUTE
|
|
||||||
* scankeys properly. Currently, the planner is careful never to generate
|
|
||||||
* any indexquals that would require SK_COMMUTE to be set. Someday we ought
|
|
||||||
* to try to fix this, though it's not real critical as long as indexable
|
|
||||||
* operators all have commutators...
|
|
||||||
*
|
|
||||||
* Note: this routine invokes comparison operators via OidFunctionCallN,
|
|
||||||
* ie, without caching function lookups. No point in trying to be smarter,
|
|
||||||
* since these comparisons are executed only when the user expresses a
|
|
||||||
* hokey qualification, and happen only once per scan anyway.
|
|
||||||
*----------
|
*----------
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -208,7 +207,6 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
int numberOfKeys = so->numberOfKeys;
|
int numberOfKeys = so->numberOfKeys;
|
||||||
ScanKey key;
|
ScanKey key;
|
||||||
ScanKey cur;
|
ScanKey cur;
|
||||||
StrategyMap map;
|
|
||||||
Datum test;
|
Datum test;
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
@ -229,6 +227,32 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
@ -243,11 +267,7 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
relation->rd_rel->relnatts == 1)
|
relation->rd_rel->relnatts == 1)
|
||||||
{
|
{
|
||||||
/* it's a unique index, do we have an equality qual? */
|
/* it's a unique index, do we have an equality qual? */
|
||||||
map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
|
if (cur->sk_strategy == BTEqualStrategyNumber)
|
||||||
BTMaxStrategyNumber,
|
|
||||||
1);
|
|
||||||
j = _bt_getstrategynumber(cur->sk_procedure, map);
|
|
||||||
if (j == (BTEqualStrategyNumber - 1))
|
|
||||||
scan->keys_are_unique = true;
|
scan->keys_are_unique = true;
|
||||||
}
|
}
|
||||||
so->numberOfRequiredKeys = 1;
|
so->numberOfRequiredKeys = 1;
|
||||||
@ -267,9 +287,6 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
* any; init[i] is TRUE if we have found such a key for this attr.
|
* any; init[i] is TRUE if we have found such a key for this attr.
|
||||||
*/
|
*/
|
||||||
attno = 1;
|
attno = 1;
|
||||||
map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
|
|
||||||
BTMaxStrategyNumber,
|
|
||||||
attno);
|
|
||||||
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
||||||
MemSet(init, 0, sizeof(init));
|
MemSet(init, 0, sizeof(init));
|
||||||
|
|
||||||
@ -324,7 +341,7 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
j == (BTEqualStrategyNumber - 1))
|
j == (BTEqualStrategyNumber - 1))
|
||||||
continue;
|
continue;
|
||||||
chk = &xform[j];
|
chk = &xform[j];
|
||||||
test = OidFunctionCall2(chk->sk_procedure,
|
test = FunctionCall2(&chk->sk_func,
|
||||||
eq->sk_argument,
|
eq->sk_argument,
|
||||||
chk->sk_argument);
|
chk->sk_argument);
|
||||||
if (!DatumGetBool(test))
|
if (!DatumGetBool(test))
|
||||||
@ -350,7 +367,7 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];
|
ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];
|
||||||
ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];
|
ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];
|
||||||
|
|
||||||
test = OidFunctionCall2(le->sk_procedure,
|
test = FunctionCall2(&le->sk_func,
|
||||||
lt->sk_argument,
|
lt->sk_argument,
|
||||||
le->sk_argument);
|
le->sk_argument);
|
||||||
if (DatumGetBool(test))
|
if (DatumGetBool(test))
|
||||||
@ -366,7 +383,7 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];
|
ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];
|
||||||
ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];
|
ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];
|
||||||
|
|
||||||
test = OidFunctionCall2(ge->sk_procedure,
|
test = FunctionCall2(&ge->sk_func,
|
||||||
gt->sk_argument,
|
gt->sk_argument,
|
||||||
ge->sk_argument);
|
ge->sk_argument);
|
||||||
if (DatumGetBool(test))
|
if (DatumGetBool(test))
|
||||||
@ -404,15 +421,12 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
|
|
||||||
/* Re-initialize for new attno */
|
/* Re-initialize for new attno */
|
||||||
attno = cur->sk_attno;
|
attno = cur->sk_attno;
|
||||||
map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
|
|
||||||
BTMaxStrategyNumber,
|
|
||||||
attno);
|
|
||||||
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
|
||||||
MemSet(init, 0, sizeof(init));
|
MemSet(init, 0, sizeof(init));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* figure out which strategy this key's operator corresponds to */
|
/* figure out which strategy this key's operator corresponds to */
|
||||||
j = _bt_getstrategynumber(cur->sk_procedure, map);
|
j = cur->sk_strategy - 1;
|
||||||
|
|
||||||
/* have we seen one of these before? */
|
/* have we seen one of these before? */
|
||||||
if (init[j])
|
if (init[j])
|
||||||
@ -446,25 +460,6 @@ _bt_orderkeys(IndexScanDesc scan)
|
|||||||
scan->keys_are_unique = true;
|
scan->keys_are_unique = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine which btree strategy an operator procedure matches.
|
|
||||||
*
|
|
||||||
* Result is strategy number minus 1.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for (j = BTMaxStrategyNumber; --j >= 0;)
|
|
||||||
{
|
|
||||||
if (sk_procedure == map->entry[j].sk_procedure)
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
elog(ERROR, "could not identify operator %u", sk_procedure);
|
|
||||||
return -1; /* keep compiler quiet */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test whether an indextuple satisfies all the scankey conditions.
|
* Test whether an indextuple satisfies all the scankey conditions.
|
||||||
*
|
*
|
||||||
@ -533,14 +528,9 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key->sk_flags & SK_COMMUTE)
|
test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
|
||||||
test = FunctionCall2(&key->sk_func,
|
|
||||||
key->sk_argument, datum);
|
|
||||||
else
|
|
||||||
test = FunctionCall2(&key->sk_func,
|
|
||||||
datum, key->sk_argument);
|
|
||||||
|
|
||||||
if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE))
|
if (!DatumGetBool(test))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Tuple fails this qual. If it's a required qual, then we
|
* Tuple fails this qual. If it's a required qual, then we
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.47 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/rtree.h"
|
#include "access/rtree.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
/* routines defined and used here */
|
/* routines defined and used here */
|
||||||
@ -71,7 +71,6 @@ rtrescan(PG_FUNCTION_ARGS)
|
|||||||
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
|
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
|
||||||
ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
|
ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
|
||||||
RTreeScanOpaque p;
|
RTreeScanOpaque p;
|
||||||
RegProcedure internal_proc;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -116,14 +115,23 @@ rtrescan(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < s->numberOfKeys; i++)
|
for (i = 0; i < s->numberOfKeys; i++)
|
||||||
{
|
{
|
||||||
internal_proc = RTMapOperator(s->indexRelation,
|
AttrNumber attno = s->keyData[i].sk_attno;
|
||||||
s->keyData[i].sk_attno,
|
Oid opclass;
|
||||||
s->keyData[i].sk_procedure);
|
StrategyNumber int_strategy;
|
||||||
|
Oid int_oper;
|
||||||
|
RegProcedure int_proc;
|
||||||
|
|
||||||
|
opclass = s->indexRelation->rd_index->indclass[attno-1];
|
||||||
|
int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
|
||||||
|
int_oper = get_opclass_member(opclass, int_strategy);
|
||||||
|
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,
|
||||||
s->keyData[i].sk_attno,
|
attno,
|
||||||
internal_proc,
|
int_strategy,
|
||||||
s->keyData[i].sk_argument);
|
int_proc,
|
||||||
|
s->keyData[i].sk_argument,
|
||||||
|
s->keyData[i].sk_argtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,176 +8,18 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.22 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/istrat.h"
|
|
||||||
#include "access/rtree.h"
|
#include "access/rtree.h"
|
||||||
|
|
||||||
static StrategyNumber RelationGetRTStrategy(Relation r,
|
|
||||||
AttrNumber attnum, RegProcedure proc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: negate, commute, and negatecommute all assume that operators are
|
* Here's something peculiar to rtrees that doesn't apply to most other
|
||||||
* ordered as follows in the strategy map:
|
|
||||||
*
|
|
||||||
* left, left-or-overlap, overlap, right-or-overlap, right, same,
|
|
||||||
* contains, contained-by
|
|
||||||
*
|
|
||||||
* The negate, commute, and negatecommute arrays are used by the planner
|
|
||||||
* to plan indexed scans over data that appears in the qualificiation in
|
|
||||||
* a boolean negation, or whose operands appear in the wrong order. For
|
|
||||||
* example, if the operator "<%" means "contains", and the user says
|
|
||||||
*
|
|
||||||
* where not rel.box <% "(10,10,20,20)"::box
|
|
||||||
*
|
|
||||||
* the planner can plan an index scan by noting that rtree indices have
|
|
||||||
* an operator in their operator class for negating <%.
|
|
||||||
*
|
|
||||||
* Similarly, if the user says something like
|
|
||||||
*
|
|
||||||
* where "(10,10,20,20)"::box <% rel.box
|
|
||||||
*
|
|
||||||
* the planner can see that the rtree index on rel.box has an operator in
|
|
||||||
* its opclass for commuting <%, and plan the scan using that operator.
|
|
||||||
* This added complexity in the access methods makes the planner a lot easier
|
|
||||||
* to write.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* if a op b, what operator tells us if (not a op b)? */
|
|
||||||
static StrategyNumber RTNegate[RTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
|
|
||||||
static StrategyNumber RTCommute[RTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
|
|
||||||
static StrategyNumber RTNegateCommute[RTNStrategies] = {
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy,
|
|
||||||
InvalidStrategy
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now do the TermData arrays. These exist in case the user doesn't give
|
|
||||||
* us a full set of operators for a particular operator class. The idea
|
|
||||||
* is that by making multiple comparisons using any one of the supplied
|
|
||||||
* operators, we can decide whether two n-dimensional polygons are equal.
|
|
||||||
* For example, if a contains b and b contains a, we may conclude that
|
|
||||||
* a and b are equal.
|
|
||||||
*
|
|
||||||
* The presence of the TermData arrays in all this is a historical accident.
|
|
||||||
* Early in the development of the POSTGRES access methods, it was believed
|
|
||||||
* that writing functions was harder than writing arrays. This is wrong;
|
|
||||||
* TermData is hard to understand and hard to get right. In general, when
|
|
||||||
* someone populates a new operator class, they populate it completely. If
|
|
||||||
* Mike Hirohama had forced Cimarron Taylor to populate the strategy map
|
|
||||||
* for btree int2_ops completely in 1988, you wouldn't have to deal with
|
|
||||||
* all this now. Too bad for you.
|
|
||||||
*
|
|
||||||
* Since you can't necessarily do this in all cases (for example, you can't
|
|
||||||
* do it given only "intersects" or "disjoint"), TermData arrays for some
|
|
||||||
* operators don't appear below.
|
|
||||||
*
|
|
||||||
* Note that if you DO supply all the operators required in a given opclass
|
|
||||||
* by inserting them into the pg_opclass system catalog, you can get away
|
|
||||||
* without doing all this TermData stuff. Since the rtree code is intended
|
|
||||||
* to be a reference for access method implementors, I'm doing TermData
|
|
||||||
* correctly here.
|
|
||||||
*
|
|
||||||
* Note on style: these are all actually of type StrategyTermData, but
|
|
||||||
* since those have variable-length data at the end of the struct we can't
|
|
||||||
* properly initialize them if we declare them to be what they are.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* if you only have "contained-by", how do you determine equality? */
|
|
||||||
static uint16 RTContainedByTermData[] = {
|
|
||||||
2, /* make two comparisons */
|
|
||||||
RTContainedByStrategyNumber, /* use "a contained-by b" */
|
|
||||||
0x0, /* without any magic */
|
|
||||||
RTContainedByStrategyNumber, /* then use contained-by, */
|
|
||||||
SK_COMMUTE /* swapping a and b */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* if you only have "contains", how do you determine equality? */
|
|
||||||
static uint16 RTContainsTermData[] = {
|
|
||||||
2, /* make two comparisons */
|
|
||||||
RTContainsStrategyNumber, /* use "a contains b" */
|
|
||||||
0x0, /* without any magic */
|
|
||||||
RTContainsStrategyNumber, /* then use contains again, */
|
|
||||||
SK_COMMUTE /* swapping a and b */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* now put all that together in one place for the planner */
|
|
||||||
static StrategyTerm RTEqualExpressionData[] = {
|
|
||||||
(StrategyTerm) RTContainedByTermData,
|
|
||||||
(StrategyTerm) RTContainsTermData,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If you were sufficiently attentive to detail, you would go through
|
|
||||||
* the ExpressionData pain above for every one of the seven strategies
|
|
||||||
* we defined. I am not. Now we declare the StrategyEvaluationData
|
|
||||||
* structure that gets shipped around to help the planner and the access
|
|
||||||
* method decide what sort of scan it should do, based on (a) what the
|
|
||||||
* user asked for, (b) what operators are defined for a particular opclass,
|
|
||||||
* and (c) the reams of information we supplied above.
|
|
||||||
*
|
|
||||||
* The idea of all of this initialized data is to make life easier on the
|
|
||||||
* user when he defines a new operator class to use this access method.
|
|
||||||
* By filling in all the data, we let him get away with leaving holes in his
|
|
||||||
* operator class, and still let him use the index. The added complexity
|
|
||||||
* in the access methods just isn't worth the trouble, though.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static StrategyExpression RTEvaluationExpressions[RTNStrategies] = {
|
|
||||||
NULL, /* express left */
|
|
||||||
NULL, /* express overleft */
|
|
||||||
NULL, /* express overlap */
|
|
||||||
NULL, /* express overright */
|
|
||||||
NULL, /* express right */
|
|
||||||
(StrategyExpression) RTEqualExpressionData, /* express same */
|
|
||||||
NULL, /* express contains */
|
|
||||||
NULL /* express contained-by */
|
|
||||||
};
|
|
||||||
|
|
||||||
static StrategyEvaluationData RTEvaluationData = {
|
|
||||||
RTNStrategies, /* # of strategies */
|
|
||||||
(StrategyTransformMap) RTNegate, /* how to do (not qual) */
|
|
||||||
(StrategyTransformMap) RTCommute, /* how to swap operands */
|
|
||||||
(StrategyTransformMap) RTNegateCommute, /* how to do both */
|
|
||||||
RTEvaluationExpressions
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Okay, now something peculiar to rtrees that doesn't apply to most other
|
|
||||||
* indexing structures: When we're searching a tree for a given value, we
|
* indexing structures: When we're searching a tree for a given value, we
|
||||||
* can't do the same sorts of comparisons on internal node entries as we
|
* can't do the same sorts of comparisons on internal node entries as we
|
||||||
* do at leaves. The reason is that if we're looking for (say) all boxes
|
* do at leaves. The reason is that if we're looking for (say) all boxes
|
||||||
@ -191,7 +33,7 @@ static StrategyEvaluationData RTEvaluationData = {
|
|||||||
* left, left-or-overlap, overlap, right-or-overlap, right, same,
|
* left, left-or-overlap, overlap, right-or-overlap, right, same,
|
||||||
* contains, contained-by
|
* contains, contained-by
|
||||||
*/
|
*/
|
||||||
static StrategyNumber RTOperMap[RTNStrategies] = {
|
static const StrategyNumber RTOperMap[RTNStrategies] = {
|
||||||
RTOverLeftStrategyNumber,
|
RTOverLeftStrategyNumber,
|
||||||
RTOverLeftStrategyNumber,
|
RTOverLeftStrategyNumber,
|
||||||
RTOverlapStrategyNumber,
|
RTOverlapStrategyNumber,
|
||||||
@ -202,39 +44,10 @@ static StrategyNumber RTOperMap[RTNStrategies] = {
|
|||||||
RTOverlapStrategyNumber
|
RTOverlapStrategyNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
static StrategyNumber
|
|
||||||
RelationGetRTStrategy(Relation r,
|
StrategyNumber
|
||||||
AttrNumber attnum,
|
RTMapToInternalOperator(StrategyNumber strat)
|
||||||
RegProcedure proc)
|
|
||||||
{
|
{
|
||||||
return RelationGetStrategy(r, attnum, &RTEvaluationData, proc);
|
Assert(strat > 0 && strat <= RTNStrategies);
|
||||||
}
|
return RTOperMap[strat - 1];
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
bool
|
|
||||||
RelationInvokeRTStrategy(Relation r,
|
|
||||||
AttrNumber attnum,
|
|
||||||
StrategyNumber s,
|
|
||||||
Datum left,
|
|
||||||
Datum right)
|
|
||||||
{
|
|
||||||
return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
|
|
||||||
left, right));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RegProcedure
|
|
||||||
RTMapOperator(Relation r,
|
|
||||||
AttrNumber attnum,
|
|
||||||
RegProcedure proc)
|
|
||||||
{
|
|
||||||
StrategyNumber procstrat;
|
|
||||||
StrategyMap strategyMap;
|
|
||||||
|
|
||||||
procstrat = RelationGetRTStrategy(r, attnum, proc);
|
|
||||||
strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r),
|
|
||||||
RTNStrategies,
|
|
||||||
attnum);
|
|
||||||
|
|
||||||
return strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure;
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.60 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.61 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -23,7 +23,6 @@
|
|||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "access/itup.h"
|
#include "access/itup.h"
|
||||||
#include "access/skey.h"
|
#include "access/skey.h"
|
||||||
#include "access/strat.h"
|
|
||||||
#include "access/tupdesc.h"
|
#include "access/tupdesc.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "bootstrap/bootstrap.h"
|
#include "bootstrap/bootstrap.h"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.30 2003/08/04 02:39:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.31 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,7 +21,6 @@
|
|||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "access/itup.h"
|
#include "access/itup.h"
|
||||||
#include "access/skey.h"
|
#include "access/skey.h"
|
||||||
#include "access/strat.h"
|
|
||||||
#include "access/tupdesc.h"
|
#include "access/tupdesc.h"
|
||||||
#include "bootstrap/bootstrap.h"
|
#include "bootstrap/bootstrap.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.91 2003/10/31 20:00:49 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.92 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -367,8 +367,9 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
|||||||
|
|
||||||
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
||||||
ScanKeyEntryInitialize(&entry[0], 0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
Anum_pg_database_datname, F_NAMEEQ,
|
Anum_pg_database_datname,
|
||||||
CStringGetDatum(dbname));
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
CStringGetDatum(dbname), NAMEOID);
|
||||||
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))
|
||||||
@ -1130,9 +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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(db_oid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(db_oid), OIDOID);
|
||||||
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))
|
||||||
@ -1529,9 +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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(db_oid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(db_oid), OIDOID);
|
||||||
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.31 2003/08/11 23:04:49 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.32 2003/11/09 21:30:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#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"
|
||||||
@ -282,17 +283,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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_refclassid, F_OIDEQ,
|
Anum_pg_depend_refclassid,
|
||||||
ObjectIdGetDatum(object->classId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ObjectIdGetDatum(object->classId), OIDOID);
|
||||||
Anum_pg_depend_refobjid, F_OIDEQ,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
ObjectIdGetDatum(object->objectId));
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId), OIDOID);
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0x0,
|
ScanKeyEntryInitialize(&key[2], 0,
|
||||||
Anum_pg_depend_refobjsubid, F_INT4EQ,
|
Anum_pg_depend_refobjsubid,
|
||||||
Int32GetDatum(object->objectSubId));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(object->objectSubId), INT4OID);
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -414,17 +418,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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_classid, F_OIDEQ,
|
Anum_pg_depend_classid,
|
||||||
ObjectIdGetDatum(object->classId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ObjectIdGetDatum(object->classId), OIDOID);
|
||||||
Anum_pg_depend_objid, F_OIDEQ,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
ObjectIdGetDatum(object->objectId));
|
Anum_pg_depend_objid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId), OIDOID);
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0x0,
|
ScanKeyEntryInitialize(&key[2], 0,
|
||||||
Anum_pg_depend_objsubid, F_INT4EQ,
|
Anum_pg_depend_objsubid,
|
||||||
Int32GetDatum(object->objectSubId));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(object->objectSubId), INT4OID);
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -644,17 +651,20 @@ deleteDependentObjects(const ObjectAddress *object,
|
|||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
ObjectAddress otherObject;
|
ObjectAddress otherObject;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_refclassid, F_OIDEQ,
|
Anum_pg_depend_refclassid,
|
||||||
ObjectIdGetDatum(object->classId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ObjectIdGetDatum(object->classId), OIDOID);
|
||||||
Anum_pg_depend_refobjid, F_OIDEQ,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
ObjectIdGetDatum(object->objectId));
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId), OIDOID);
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[2], 0x0,
|
ScanKeyEntryInitialize(&key[2], 0,
|
||||||
Anum_pg_depend_refobjsubid, F_INT4EQ,
|
Anum_pg_depend_refobjsubid,
|
||||||
Int32GetDatum(object->objectSubId));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(object->objectSubId), INT4OID);
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1463,9 +1473,11 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
castDesc = heap_openr(CastRelationName, AccessShareLock);
|
castDesc = heap_openr(CastRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
rcscan = systable_beginscan(castDesc, CastOidIndex, true,
|
rcscan = systable_beginscan(castDesc, CastOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -1497,9 +1509,11 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -1556,12 +1570,14 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, true,
|
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex,
|
||||||
SnapshotNow, 1, skey);
|
true, SnapshotNow, 1, skey);
|
||||||
|
|
||||||
tup = systable_getnext(adscan);
|
tup = systable_getnext(adscan);
|
||||||
|
|
||||||
@ -1656,9 +1672,11 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
|
ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
|
rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -1690,9 +1708,11 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
|
trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
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.253 2003/09/25 06:57:57 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.254 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -853,9 +853,11 @@ RelationRemoveInheritance(Relation relation)
|
|||||||
|
|
||||||
catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
|
catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0x0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_inherits_inhrelid, F_OIDEQ,
|
Anum_pg_inherits_inhrelid,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelationGetRelid(relation)),
|
||||||
|
OIDOID);
|
||||||
|
|
||||||
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
|
scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
|
||||||
SnapshotNow, 1, &key);
|
SnapshotNow, 1, &key);
|
||||||
@ -918,9 +920,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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_attribute_attrelid, F_OIDEQ,
|
Anum_pg_attribute_attrelid,
|
||||||
ObjectIdGetDatum(relid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
scan = systable_beginscan(attrel, AttributeRelidNumIndex, true,
|
scan = systable_beginscan(attrel, AttributeRelidNumIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
@ -1032,12 +1035,14 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
|
|||||||
|
|
||||||
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scankeys[0], 0x0,
|
ScanKeyEntryInitialize(&scankeys[0], 0,
|
||||||
Anum_pg_attrdef_adrelid, F_OIDEQ,
|
Anum_pg_attrdef_adrelid,
|
||||||
ObjectIdGetDatum(relid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&scankeys[1], 0x0,
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
Anum_pg_attrdef_adnum, F_INT2EQ,
|
ScanKeyEntryInitialize(&scankeys[1], 0,
|
||||||
Int16GetDatum(attnum));
|
Anum_pg_attrdef_adnum,
|
||||||
|
BTEqualStrategyNumber, F_INT2EQ,
|
||||||
|
Int16GetDatum(attnum), INT2OID);
|
||||||
|
|
||||||
scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
|
scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
|
||||||
SnapshotNow, 2, scankeys);
|
SnapshotNow, 2, scankeys);
|
||||||
@ -1087,9 +1092,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], 0x0,
|
ScanKeyEntryInitialize(&scankeys[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(attrdefId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(attrdefId), OIDOID);
|
||||||
|
|
||||||
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true,
|
scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true,
|
||||||
SnapshotNow, 1, scankeys);
|
SnapshotNow, 1, scankeys);
|
||||||
@ -1823,9 +1829,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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_constraint_conrelid, F_OIDEQ,
|
Anum_pg_constraint_conrelid,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
||||||
|
|
||||||
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
@ -1876,17 +1883,19 @@ RemoveStatistics(Relation rel, AttrNumber attnum)
|
|||||||
|
|
||||||
pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
|
pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_statistic_starelid, F_OIDEQ,
|
Anum_pg_statistic_starelid,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
||||||
|
|
||||||
if (attnum == 0)
|
if (attnum == 0)
|
||||||
nkeys = 1;
|
nkeys = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
Anum_pg_statistic_staattnum, F_INT2EQ,
|
Anum_pg_statistic_staattnum,
|
||||||
Int16GetDatum(attnum));
|
BTEqualStrategyNumber, F_INT2EQ,
|
||||||
|
Int16GetDatum(attnum), INT2OID);
|
||||||
nkeys = 2;
|
nkeys = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2043,8 +2052,8 @@ heap_truncate_check_FKs(Relation rel)
|
|||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_constraint_confrelid,
|
Anum_pg_constraint_confrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
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.219 2003/09/29 00:05:24 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.220 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/istrat.h"
|
|
||||||
#include "bootstrap/bootstrap.h"
|
#include "bootstrap/bootstrap.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
@ -995,8 +994,8 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
|
|||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
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);
|
||||||
@ -1198,8 +1197,8 @@ UpdateStats(Oid relid, double reltuples)
|
|||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
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.16 2003/08/04 02:39:58 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.17 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -281,13 +281,15 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con
|
|||||||
|
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_constraint_conname, F_NAMEEQ,
|
Anum_pg_constraint_conname,
|
||||||
CStringGetDatum(cname));
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
CStringGetDatum(cname), NAMEOID);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0x0,
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
Anum_pg_constraint_connamespace, F_OIDEQ,
|
Anum_pg_constraint_connamespace,
|
||||||
ObjectIdGetDatum(objNamespace));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(objNamespace), OIDOID);
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
@ -353,13 +355,15 @@ GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, i
|
|||||||
*/
|
*/
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_constraint_conname, F_NAMEEQ,
|
Anum_pg_constraint_conname,
|
||||||
CStringGetDatum(cname));
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
CStringGetDatum(cname), NAMEOID);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0x0,
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
Anum_pg_constraint_connamespace, F_OIDEQ,
|
Anum_pg_constraint_connamespace,
|
||||||
ObjectIdGetDatum(objNamespace));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(objNamespace), OIDOID);
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
@ -418,9 +422,10 @@ RemoveConstraintById(Oid conId)
|
|||||||
|
|
||||||
conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(conId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(conId), OIDOID);
|
||||||
|
|
||||||
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.15 2003/08/04 02:39:58 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.16 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#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"
|
||||||
@ -176,11 +177,10 @@ RemoveConversionById(Oid conversionOid)
|
|||||||
HeapScanDesc scan;
|
HeapScanDesc scan;
|
||||||
ScanKeyData scanKeyData;
|
ScanKeyData scanKeyData;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scanKeyData,
|
ScanKeyEntryInitialize(&scanKeyData, 0,
|
||||||
0,
|
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(conversionOid));
|
ObjectIdGetDatum(conversionOid), OIDOID);
|
||||||
|
|
||||||
/* 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.7 2003/08/04 02:39:58 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.8 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@ -138,12 +139,14 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId)
|
|||||||
|
|
||||||
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_classid, F_OIDEQ,
|
Anum_pg_depend_classid,
|
||||||
ObjectIdGetDatum(classId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ObjectIdGetDatum(classId), OIDOID);
|
||||||
Anum_pg_depend_objid, F_OIDEQ,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
ObjectIdGetDatum(objectId));
|
Anum_pg_depend_objid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(objectId), OIDOID);
|
||||||
|
|
||||||
scan = systable_beginscan(depRel, DependDependerIndex, true,
|
scan = systable_beginscan(depRel, DependDependerIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
@ -178,13 +181,15 @@ isObjectPinned(const ObjectAddress *object, Relation rel)
|
|||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
ScanKeyData key[2];
|
ScanKeyData key[2];
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_refclassid, F_OIDEQ,
|
Anum_pg_depend_refclassid,
|
||||||
ObjectIdGetDatum(object->classId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->classId), OIDOID);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
Anum_pg_depend_refobjid, F_OIDEQ,
|
Anum_pg_depend_refobjid,
|
||||||
ObjectIdGetDatum(object->objectId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(object->objectId), OIDOID);
|
||||||
|
|
||||||
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.17 2003/09/24 18:54:01 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.18 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#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"
|
||||||
@ -81,10 +82,10 @@ LargeObjectDrop(Oid loid)
|
|||||||
SysScanDesc sd;
|
SysScanDesc sd;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
(RegProcedure) F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(loid));
|
ObjectIdGetDatum(loid), OIDOID);
|
||||||
|
|
||||||
pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
|
pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
@ -119,10 +120,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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_largeobject_loid,
|
Anum_pg_largeobject_loid,
|
||||||
(RegProcedure) F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(loid));
|
ObjectIdGetDatum(loid), OIDOID);
|
||||||
|
|
||||||
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.102 2003/10/16 16:50:41 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.103 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -80,6 +80,7 @@
|
|||||||
#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"
|
||||||
@ -354,8 +355,8 @@ Async_UnlistenAll(void)
|
|||||||
/* Find and delete all entries with my listenerPID */
|
/* Find and delete all entries with my listenerPID */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_listener_pid,
|
Anum_pg_listener_pid,
|
||||||
F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(MyProcPid));
|
Int32GetDatum(MyProcPid), INT4OID);
|
||||||
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)
|
||||||
@ -818,8 +819,8 @@ ProcessIncomingNotify(void)
|
|||||||
/* Scan only entries with my listenerPID */
|
/* Scan only entries with my listenerPID */
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_listener_pid,
|
Anum_pg_listener_pid,
|
||||||
F_INT4EQ,
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
Int32GetDatum(MyProcPid));
|
Int32GetDatum(MyProcPid), INT4OID);
|
||||||
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.116 2003/09/25 06:57:58 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.117 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#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"
|
||||||
@ -880,8 +881,8 @@ get_tables_to_cluster(MemoryContext cluster_context)
|
|||||||
indRelation = relation_openr(IndexRelationName, AccessShareLock);
|
indRelation = relation_openr(IndexRelationName, AccessShareLock);
|
||||||
ScanKeyEntryInitialize(&entry, 0,
|
ScanKeyEntryInitialize(&entry, 0,
|
||||||
Anum_pg_index_indisclustered,
|
Anum_pg_index_indisclustered,
|
||||||
F_BOOLEQ,
|
BTEqualStrategyNumber, F_BOOLEQ,
|
||||||
BoolGetDatum(true));
|
BoolGetDatum(true), BOOLOID);
|
||||||
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.71 2003/09/25 06:57:58 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.72 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -156,23 +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],
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_description_objoid,
|
||||||
(AttrNumber) 1,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) F_OIDEQ,
|
ObjectIdGetDatum(oid), OIDOID);
|
||||||
ObjectIdGetDatum(oid));
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
|
Anum_pg_description_classoid,
|
||||||
ScanKeyEntryInitialize(&skey[1],
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(bits16) 0x0,
|
ObjectIdGetDatum(classoid), OIDOID);
|
||||||
(AttrNumber) 2,
|
ScanKeyEntryInitialize(&skey[2], 0,
|
||||||
(RegProcedure) F_OIDEQ,
|
Anum_pg_description_objsubid,
|
||||||
ObjectIdGetDatum(classoid));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(subid), INT4OID);
|
||||||
ScanKeyEntryInitialize(&skey[2],
|
|
||||||
(bits16) 0x0,
|
|
||||||
(AttrNumber) 3,
|
|
||||||
(RegProcedure) F_INT4EQ,
|
|
||||||
Int32GetDatum(subid));
|
|
||||||
|
|
||||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
@ -236,19 +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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_description_objoid, F_OIDEQ,
|
Anum_pg_description_objoid,
|
||||||
ObjectIdGetDatum(oid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(oid), OIDOID);
|
||||||
ScanKeyEntryInitialize(&skey[1], 0x0,
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
Anum_pg_description_classoid, F_OIDEQ,
|
Anum_pg_description_classoid,
|
||||||
ObjectIdGetDatum(classoid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(classoid), OIDOID);
|
||||||
|
|
||||||
if (subid != 0)
|
if (subid != 0)
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&skey[2], 0x0,
|
ScanKeyEntryInitialize(&skey[2], 0,
|
||||||
Anum_pg_description_objsubid, F_INT4EQ,
|
Anum_pg_description_objsubid,
|
||||||
Int32GetDatum(subid));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(subid), INT4OID);
|
||||||
nkeys = 3;
|
nkeys = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -541,11 +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,
|
ScanKeyEntryInitialize(&scanKeyData, 0,
|
||||||
0,
|
|
||||||
Anum_pg_rewrite_rulename,
|
Anum_pg_rewrite_rulename,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(rulename));
|
PointerGetDatum(rulename), NAMEOID);
|
||||||
|
|
||||||
RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
|
RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
|
scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
|
||||||
@ -795,14 +791,15 @@ 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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
ObjectIdGetDatum(RelationGetRelid(relation)),
|
||||||
ScanKeyEntryInitialize(&entry[1], 0x0,
|
OIDOID);
|
||||||
|
ScanKeyEntryInitialize(&entry[1], 0,
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(trigname));
|
CStringGetDatum(trigname), NAMEOID);
|
||||||
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);
|
||||||
@ -875,9 +872,11 @@ CommentConstraint(List *qualname, char *comment)
|
|||||||
*/
|
*/
|
||||||
pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
|
pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_constraint_conrelid, F_OIDEQ,
|
Anum_pg_constraint_conrelid,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
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.124 2003/09/29 00:05:24 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.125 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#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"
|
||||||
@ -530,10 +531,13 @@ 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, ObjectIdAttributeNumber,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
F_OIDEQ, ObjectIdGetDatum(db_id));
|
ObjectIdAttributeNumber,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(db_id), OIDOID);
|
||||||
|
|
||||||
pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true, SnapshotNow, 1, &key);
|
pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true,
|
||||||
|
SnapshotNow, 1, &key);
|
||||||
|
|
||||||
tup = systable_getnext(pgdbscan);
|
tup = systable_getnext(pgdbscan);
|
||||||
if (!HeapTupleIsValid(tup))
|
if (!HeapTupleIsValid(tup))
|
||||||
@ -612,9 +616,12 @@ RenameDatabase(const char *oldname, const char *newname)
|
|||||||
*/
|
*/
|
||||||
rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
F_NAMEEQ, NameGetDatum(oldname));
|
Anum_pg_database_datname,
|
||||||
scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key);
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
NameGetDatum(oldname), NAMEOID);
|
||||||
|
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
|
SnapshotNow, 1, &key);
|
||||||
|
|
||||||
tup = systable_getnext(scan);
|
tup = systable_getnext(scan);
|
||||||
if (!HeapTupleIsValid(tup))
|
if (!HeapTupleIsValid(tup))
|
||||||
@ -644,9 +651,12 @@ 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, Anum_pg_database_datname,
|
ScanKeyEntryInitialize(&key2, 0,
|
||||||
F_NAMEEQ, NameGetDatum(newname));
|
Anum_pg_database_datname,
|
||||||
scan2 = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key2);
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
NameGetDatum(newname), NAMEOID);
|
||||||
|
scan2 = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
|
SnapshotNow, 1, &key2);
|
||||||
if (HeapTupleIsValid(systable_getnext(scan2)))
|
if (HeapTupleIsValid(systable_getnext(scan2)))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DUPLICATE_DATABASE),
|
(errcode(ERRCODE_DUPLICATE_DATABASE),
|
||||||
@ -702,9 +712,12 @@ 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, Anum_pg_database_datname,
|
ScanKeyEntryInitialize(&scankey, 0,
|
||||||
F_NAMEEQ, NameGetDatum(stmt->dbname));
|
Anum_pg_database_datname,
|
||||||
scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &scankey);
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
NameGetDatum(stmt->dbname), NAMEOID);
|
||||||
|
scan = systable_beginscan(rel, DatabaseNameIndex, true,
|
||||||
|
SnapshotNow, 1, &scankey);
|
||||||
tuple = systable_getnext(scan);
|
tuple = systable_getnext(scan);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -782,10 +795,13 @@ 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, Anum_pg_database_datname,
|
ScanKeyEntryInitialize(&scanKey, 0,
|
||||||
F_NAMEEQ, NameGetDatum(name));
|
Anum_pg_database_datname,
|
||||||
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
NameGetDatum(name), NAMEOID);
|
||||||
|
|
||||||
scan = systable_beginscan(relation, DatabaseNameIndex, true, SnapshotNow, 1, &scanKey);
|
scan = systable_beginscan(relation, DatabaseNameIndex, true,
|
||||||
|
SnapshotNow, 1, &scanKey);
|
||||||
|
|
||||||
tuple = systable_getnext(scan);
|
tuple = systable_getnext(scan);
|
||||||
|
|
||||||
@ -985,10 +1001,12 @@ 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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
Anum_pg_database_datname, F_NAMEEQ,
|
Anum_pg_database_datname,
|
||||||
CStringGetDatum(dbname));
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
scan = systable_beginscan(pg_database, DatabaseNameIndex, true, SnapshotNow, 1, entry);
|
CStringGetDatum(dbname), NAMEOID);
|
||||||
|
scan = systable_beginscan(pg_database, DatabaseNameIndex, true,
|
||||||
|
SnapshotNow, 1, entry);
|
||||||
|
|
||||||
dbtuple = systable_getnext(scan);
|
dbtuple = systable_getnext(scan);
|
||||||
|
|
||||||
@ -1023,10 +1041,12 @@ 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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(dbid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
scan = systable_beginscan(pg_database, DatabaseOidIndex, true, SnapshotNow, 1, entry);
|
ObjectIdGetDatum(dbid), OIDOID);
|
||||||
|
scan = systable_beginscan(pg_database, DatabaseOidIndex, true,
|
||||||
|
SnapshotNow, 1, entry);
|
||||||
|
|
||||||
dbtuple = systable_getnext(scan);
|
dbtuple = systable_getnext(scan);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.38 2003/10/02 06:34:03 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.39 2003/11/09 21:30:36 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, 0x0,
|
ScanKeyEntryInitialize(&scankey, 0,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(castOid));
|
ObjectIdGetDatum(castOid), OIDOID);
|
||||||
scan = systable_beginscan(relation, CastOidIndex, true,
|
scan = systable_beginscan(relation, CastOidIndex, true,
|
||||||
SnapshotNow, 1, &scankey);
|
SnapshotNow, 1, &scankey);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.21 2003/09/26 15:27:31 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.22 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#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_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
@ -270,9 +271,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
|||||||
ScanKeyData skey[1];
|
ScanKeyData skey[1];
|
||||||
SysScanDesc scan;
|
SysScanDesc scan;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_opclass_opcamid, F_OIDEQ,
|
Anum_pg_opclass_opcamid,
|
||||||
ObjectIdGetDatum(amoid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(amoid), OIDOID);
|
||||||
|
|
||||||
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -589,8 +591,9 @@ RemoveOpClassById(Oid opclassOid)
|
|||||||
* Remove associated entries in pg_amop.
|
* Remove associated entries in pg_amop.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_amop_amopclaid, F_OIDEQ,
|
Anum_pg_amop_amopclaid,
|
||||||
ObjectIdGetDatum(opclassOid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(opclassOid), OIDOID);
|
||||||
|
|
||||||
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
@ -607,8 +610,9 @@ RemoveOpClassById(Oid opclassOid)
|
|||||||
* Remove associated entries in pg_amproc.
|
* Remove associated entries in pg_amproc.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_amproc_amopclaid, F_OIDEQ,
|
Anum_pg_amproc_amopclaid,
|
||||||
ObjectIdGetDatum(opclassOid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(opclassOid), OIDOID);
|
||||||
|
|
||||||
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.91 2003/10/13 22:47:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.92 2003/11/09 21:30:36 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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_trigger_tgconstrrelid,
|
Anum_pg_trigger_tgconstrrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
|
trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
|
||||||
true, SnapshotNow,
|
true, SnapshotNow,
|
||||||
1, skey);
|
1, skey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
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.160 2003/11/06 22:08:14 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.161 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -255,8 +255,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
|||||||
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
|
||||||
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,13 +465,15 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
|
|||||||
*/
|
*/
|
||||||
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_trigger_tgrelid, F_OIDEQ,
|
Anum_pg_trigger_tgrelid,
|
||||||
ObjectIdGetDatum(relid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1], 0x0,
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
Anum_pg_trigger_tgname, F_NAMEEQ,
|
Anum_pg_trigger_tgname,
|
||||||
CStringGetDatum(trigname));
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
CStringGetDatum(trigname), NAMEOID);
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
|
||||||
SnapshotNow, 2, skey);
|
SnapshotNow, 2, skey);
|
||||||
@ -522,9 +524,10 @@ RemoveTriggerById(Oid trigOid)
|
|||||||
/*
|
/*
|
||||||
* Find the trigger to delete.
|
* Find the trigger to delete.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(trigOid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(trigOid), OIDOID);
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -640,12 +643,12 @@ renametrig(Oid relid,
|
|||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(newname));
|
PointerGetDatum(newname), NAMEOID);
|
||||||
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)))
|
||||||
@ -660,12 +663,12 @@ renametrig(Oid relid,
|
|||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_trigger_tgrelid,
|
Anum_pg_trigger_tgrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(relid));
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
Anum_pg_trigger_tgname,
|
Anum_pg_trigger_tgname,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(oldname));
|
PointerGetDatum(oldname), NAMEOID);
|
||||||
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)))
|
||||||
@ -741,11 +744,11 @@ 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,
|
ScanKeyEntryInitialize(&skey, 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_trigger_tgrelid,
|
||||||
(AttrNumber) Anum_pg_trigger_tgrelid,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) 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,
|
||||||
@ -2259,10 +2262,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
|||||||
/*
|
/*
|
||||||
* Setup to scan pg_trigger by tgconstrname ...
|
* Setup to scan pg_trigger by tgconstrname ...
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey, (bits16) 0x0,
|
ScanKeyEntryInitialize(&skey, 0,
|
||||||
(AttrNumber) Anum_pg_trigger_tgconstrname,
|
Anum_pg_trigger_tgconstrname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
PointerGetDatum(cname));
|
PointerGetDatum(cname), NAMEOID);
|
||||||
|
|
||||||
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.48 2003/10/02 06:34:03 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.49 2003/11/09 21:30:36 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,9 +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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_constraint_contypid, F_OIDEQ,
|
Anum_pg_constraint_contypid,
|
||||||
ObjectIdGetDatum(HeapTupleGetOid(tup)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(HeapTupleGetOid(tup)), OIDOID);
|
||||||
|
|
||||||
conscan = systable_beginscan(conrel, ConstraintTypidIndex, true,
|
conscan = systable_beginscan(conrel, ConstraintTypidIndex, true,
|
||||||
SnapshotNow, 1, key);
|
SnapshotNow, 1, key);
|
||||||
@ -1614,12 +1615,14 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
|
|||||||
*/
|
*/
|
||||||
depRel = relation_openr(DependRelationName, AccessShareLock);
|
depRel = relation_openr(DependRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_depend_refclassid, F_OIDEQ,
|
Anum_pg_depend_refclassid,
|
||||||
ObjectIdGetDatum(RelOid_pg_type));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ScanKeyEntryInitialize(&key[1], 0x0,
|
ObjectIdGetDatum(RelOid_pg_type), OIDOID);
|
||||||
Anum_pg_depend_refobjid, F_OIDEQ,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
ObjectIdGetDatum(domainOid));
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(domainOid), OIDOID);
|
||||||
|
|
||||||
depScan = systable_beginscan(depRel, DependReferenceIndex, true,
|
depScan = systable_beginscan(depRel, DependReferenceIndex, true,
|
||||||
SnapshotNow, 2, key);
|
SnapshotNow, 2, key);
|
||||||
@ -1898,9 +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], 0x0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_constraint_contypid, F_OIDEQ,
|
Anum_pg_constraint_contypid,
|
||||||
ObjectIdGetDatum(typeOid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(typeOid), OIDOID);
|
||||||
|
|
||||||
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.128 2003/10/02 06:36:37 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.129 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1074,9 +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, 0x0,
|
ScanKeyEntryInitialize(&scankey, 0,
|
||||||
Anum_pg_database_datdba, F_INT4EQ,
|
Anum_pg_database_datdba,
|
||||||
Int32GetDatum(usesysid));
|
BTEqualStrategyNumber, F_INT4EQ,
|
||||||
|
Int32GetDatum(usesysid), INT4OID);
|
||||||
|
|
||||||
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.263 2003/10/02 23:19:44 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.264 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#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"
|
||||||
@ -399,10 +400,10 @@ getrels(const RangeVar *vacrel, const char *stmttype)
|
|||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
ScanKeyData key;
|
ScanKeyData key;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0x0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_class_relkind,
|
Anum_pg_class_relkind,
|
||||||
F_CHAREQ,
|
BTEqualStrategyNumber, F_CHAREQ,
|
||||||
CharGetDatum(RELKIND_RELATION));
|
CharGetDatum(RELKIND_RELATION), CHAROID);
|
||||||
|
|
||||||
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
||||||
|
|
||||||
@ -582,9 +583,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], 0x0,
|
ScanKeyEntryInitialize(&entry[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(dbid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(dbid), OIDOID);
|
||||||
|
|
||||||
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.84 2003/09/24 18:54:01 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.85 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -31,13 +31,10 @@
|
|||||||
#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"
|
||||||
|
|
||||||
|
|
||||||
#define NO_OP 0
|
|
||||||
#define LEFT_OP 1
|
|
||||||
#define RIGHT_OP 2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In a multiple-index plan, we must take care to return any given tuple
|
* In a multiple-index plan, we must take care to return any given tuple
|
||||||
* only once, even if it matches conditions of several index scans. Our
|
* only once, even if it matches conditions of several index scans. Our
|
||||||
@ -617,8 +614,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
{
|
{
|
||||||
IndexScanState *indexstate;
|
IndexScanState *indexstate;
|
||||||
List *indxqual;
|
List *indxqual;
|
||||||
|
List *indxstrategy;
|
||||||
List *indxid;
|
List *indxid;
|
||||||
List *listscan;
|
|
||||||
int i;
|
int i;
|
||||||
int numIndices;
|
int numIndices;
|
||||||
int indexPtr;
|
int indexPtr;
|
||||||
@ -713,46 +710,49 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
* build the index scan keys from the index qualification
|
* build the index scan keys from the index qualification
|
||||||
*/
|
*/
|
||||||
indxqual = node->indxqual;
|
indxqual = node->indxqual;
|
||||||
|
indxstrategy = node->indxstrategy;
|
||||||
for (i = 0; i < numIndices; i++)
|
for (i = 0; i < numIndices; i++)
|
||||||
{
|
{
|
||||||
int j;
|
List *quals;
|
||||||
List *qual;
|
List *strategies;
|
||||||
int n_keys;
|
int n_keys;
|
||||||
ScanKey scan_keys;
|
ScanKey scan_keys;
|
||||||
ExprState **run_keys;
|
ExprState **run_keys;
|
||||||
|
int j;
|
||||||
|
|
||||||
qual = lfirst(indxqual);
|
quals = lfirst(indxqual);
|
||||||
indxqual = lnext(indxqual);
|
indxqual = lnext(indxqual);
|
||||||
n_keys = length(qual);
|
strategies = lfirst(indxstrategy);
|
||||||
|
indxstrategy = lnext(indxstrategy);
|
||||||
|
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));
|
||||||
run_keys = (n_keys <= 0) ? (ExprState **) NULL :
|
run_keys = (n_keys <= 0) ? (ExprState **) NULL :
|
||||||
(ExprState **) palloc(n_keys * sizeof(ExprState *));
|
(ExprState **) palloc(n_keys * sizeof(ExprState *));
|
||||||
|
|
||||||
CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for each opclause in the given qual, convert each qual's
|
* for each opclause in the given qual, convert each qual's
|
||||||
* opclause into a single scan key
|
* opclause into a single scan key
|
||||||
*/
|
*/
|
||||||
listscan = qual;
|
|
||||||
for (j = 0; j < n_keys; j++)
|
for (j = 0; j < n_keys; j++)
|
||||||
{
|
{
|
||||||
OpExpr *clause; /* one clause of index qual */
|
OpExpr *clause; /* one clause of index qual */
|
||||||
Expr *leftop; /* expr on lhs of operator */
|
Expr *leftop; /* expr on lhs of operator */
|
||||||
Expr *rightop; /* expr on rhs ... */
|
Expr *rightop; /* expr on rhs ... */
|
||||||
bits16 flags = 0;
|
int flags = 0;
|
||||||
|
AttrNumber varattno; /* att number used in scan */
|
||||||
int scanvar; /* which var identifies varattno */
|
StrategyNumber strategy; /* op's strategy number */
|
||||||
AttrNumber varattno = 0; /* att number used in scan */
|
RegProcedure opfuncid; /* operator proc id used in scan */
|
||||||
Oid opfuncid; /* operator id used in scan */
|
Datum scanvalue; /* value used in scan (if const) */
|
||||||
Datum scanvalue = 0; /* value used in scan (if const) */
|
Oid rhstype; /* datatype of comparison value */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* extract clause information from the qualification
|
* extract clause information from the qualification
|
||||||
*/
|
*/
|
||||||
clause = (OpExpr *) lfirst(listscan);
|
clause = (OpExpr *) lfirst(quals);
|
||||||
listscan = lnext(listscan);
|
quals = lnext(quals);
|
||||||
|
strategy = lfirsti(strategies);
|
||||||
|
strategies = lnext(strategies);
|
||||||
|
|
||||||
if (!IsA(clause, OpExpr))
|
if (!IsA(clause, OpExpr))
|
||||||
elog(ERROR, "indxqual is not an OpExpr");
|
elog(ERROR, "indxqual is not an OpExpr");
|
||||||
@ -761,40 +761,17 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we figure out the contents of the index qual. The
|
* Here we figure out the contents of the index qual. The
|
||||||
* usual case is (var op const) or (const op var) which means
|
* usual case is (var op const) which means we form a scan key
|
||||||
* we form a scan key for the attribute listed in the var node
|
* for the attribute listed in the var node and use the value of
|
||||||
* and use the value of the const.
|
* the const as comparison data.
|
||||||
*
|
*
|
||||||
* If we don't have a const node, then it means that one of the
|
* If we don't have a const node, it means our scan key is a
|
||||||
* var nodes refers to the "scan" tuple and is used to
|
* function of information obtained during the execution of the
|
||||||
* determine which attribute to scan, and the other expression
|
* plan, in which case we need to recalculate the index scan key
|
||||||
* is used to calculate the value used in scanning the index.
|
* at run time. Hence, we set have_runtime_keys to true and place
|
||||||
*
|
* the appropriate subexpression in run_keys. The corresponding
|
||||||
* This means our index scan's scan key is a function of
|
|
||||||
* information obtained during the execution of the plan in
|
|
||||||
* which case we need to recalculate the index scan key at run
|
|
||||||
* time.
|
|
||||||
*
|
|
||||||
* Hence, we set have_runtime_keys to true and place the
|
|
||||||
* appropriate subexpression in run_keys. The corresponding
|
|
||||||
* scan key values are recomputed at run time.
|
* scan key values are recomputed at run time.
|
||||||
*
|
|
||||||
* XXX Although this code *thinks* it can handle an indexqual
|
|
||||||
* with the indexkey on either side, in fact it cannot.
|
|
||||||
* Indexscans only work with quals that have the indexkey on
|
|
||||||
* the left (the planner/optimizer makes sure it never passes
|
|
||||||
* anything else). The reason: the scankey machinery has no
|
|
||||||
* provision for distinguishing which side of the operator is
|
|
||||||
* the indexed attribute and which is the compared-to
|
|
||||||
* constant. It just assumes that the attribute is on the left
|
|
||||||
* :-(
|
|
||||||
*
|
|
||||||
* I am leaving this code able to support both ways, even though
|
|
||||||
* half of it is dead code, on the off chance that someone
|
|
||||||
* will fix the scankey machinery someday --- tgl 8/11/99.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
scanvar = NO_OP;
|
|
||||||
run_keys[j] = NULL;
|
run_keys[j] = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -807,67 +784,25 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
|
|
||||||
Assert(leftop != NULL);
|
Assert(leftop != NULL);
|
||||||
|
|
||||||
if (IsA(leftop, Var) &&
|
if (!(IsA(leftop, Var) &&
|
||||||
var_is_rel((Var *) leftop))
|
var_is_rel((Var *) leftop)))
|
||||||
{
|
elog(ERROR, "indxqual doesn't have key on left side");
|
||||||
/*
|
|
||||||
* if the leftop is a "rel-var", then it means that it is
|
|
||||||
* a var node which tells us which attribute to use for
|
|
||||||
* our scan key.
|
|
||||||
*/
|
|
||||||
varattno = ((Var *) leftop)->varattno;
|
varattno = ((Var *) leftop)->varattno;
|
||||||
scanvar = LEFT_OP;
|
|
||||||
}
|
|
||||||
else if (IsA(leftop, Const))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* if the leftop is a const node then it means it
|
|
||||||
* identifies the value to place in our scan key.
|
|
||||||
*/
|
|
||||||
scanvalue = ((Const *) leftop)->constvalue;
|
|
||||||
if (((Const *) leftop)->constisnull)
|
|
||||||
flags |= SK_ISNULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* otherwise, the leftop contains an expression evaluable
|
|
||||||
* at runtime to figure out the value to place in our scan
|
|
||||||
* key.
|
|
||||||
*/
|
|
||||||
have_runtime_keys = true;
|
|
||||||
run_keys[j] = ExecInitExpr(leftop, (PlanState *) indexstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now determine information in rightop
|
* now determine information in rightop
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
Assert(rightop != NULL);
|
Assert(rightop != NULL);
|
||||||
|
|
||||||
if (IsA(rightop, Var) &&
|
if (IsA(rightop, Const))
|
||||||
var_is_rel((Var *) rightop))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* here we make sure only one op identifies the
|
|
||||||
* scan-attribute...
|
|
||||||
*/
|
|
||||||
if (scanvar == LEFT_OP)
|
|
||||||
elog(ERROR, "both left and right operands are rel-vars");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if the rightop is a "rel-var", then it means that it is
|
|
||||||
* a var node which tells us which attribute to use for
|
|
||||||
* our scan key.
|
|
||||||
*/
|
|
||||||
varattno = ((Var *) rightop)->varattno;
|
|
||||||
scanvar = RIGHT_OP;
|
|
||||||
}
|
|
||||||
else if (IsA(rightop, Const))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* if the rightop is a const node then it means it
|
* if the rightop is a const node then it means it
|
||||||
@ -886,15 +821,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
*/
|
*/
|
||||||
have_runtime_keys = true;
|
have_runtime_keys = true;
|
||||||
run_keys[j] = ExecInitExpr(rightop, (PlanState *) indexstate);
|
run_keys[j] = ExecInitExpr(rightop, (PlanState *) indexstate);
|
||||||
|
scanvalue = (Datum) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* now check that at least one op tells us the scan
|
|
||||||
* attribute...
|
|
||||||
*/
|
|
||||||
if (scanvar == NO_OP)
|
|
||||||
elog(ERROR, "neither left nor right operand refer to scan relation");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the scan key's fields appropriately
|
* initialize the scan key's fields appropriately
|
||||||
*/
|
*/
|
||||||
@ -902,8 +831,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
flags,
|
flags,
|
||||||
varattno, /* attribute number to
|
varattno, /* attribute number to
|
||||||
* scan */
|
* scan */
|
||||||
|
strategy, /* op's strategy */
|
||||||
opfuncid, /* reg proc to use */
|
opfuncid, /* reg proc to use */
|
||||||
scanvalue); /* constant */
|
scanvalue, /* constant */
|
||||||
|
rhstype); /* constant's type */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -922,7 +853,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
indexstate->iss_NumScanKeys = numScanKeys;
|
indexstate->iss_NumScanKeys = numScanKeys;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If all of our keys have the form (op var const) , then we have no
|
* If all of our keys have the form (var op const), then we have no
|
||||||
* runtime keys so we store NULL in the runtime key info. Otherwise
|
* runtime keys so we store NULL in the runtime key info. Otherwise
|
||||||
* runtime key info contains an array of pointers (one for each index)
|
* runtime key info contains an array of pointers (one for each index)
|
||||||
* to arrays of flags (one for each key) which indicate that the qual
|
* to arrays of flags (one for each key) which indicate that the qual
|
||||||
@ -978,10 +909,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
* does its own locks and unlocks. (We rely on having AccessShareLock
|
* does its own locks and unlocks. (We rely on having AccessShareLock
|
||||||
* on the parent table to ensure the index won't go away!)
|
* on the parent table to ensure the index won't go away!)
|
||||||
*/
|
*/
|
||||||
listscan = indxid;
|
|
||||||
for (i = 0; i < numIndices; i++)
|
for (i = 0; i < numIndices; i++)
|
||||||
{
|
{
|
||||||
Oid indexOid = lfirsto(listscan);
|
Oid indexOid = lfirsto(indxid);
|
||||||
|
|
||||||
indexDescs[i] = index_open(indexOid);
|
indexDescs[i] = index_open(indexOid);
|
||||||
scanDescs[i] = index_beginscan(currentRelation,
|
scanDescs[i] = index_beginscan(currentRelation,
|
||||||
@ -989,7 +919,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
|||||||
estate->es_snapshot,
|
estate->es_snapshot,
|
||||||
numScanKeys[i],
|
numScanKeys[i],
|
||||||
scanKeys[i]);
|
scanKeys[i]);
|
||||||
listscan = lnext(listscan);
|
indxid = lnext(indxid);
|
||||||
}
|
}
|
||||||
|
|
||||||
indexstate->iss_RelationDescs = indexDescs;
|
indexstate->iss_RelationDescs = indexDescs;
|
||||||
|
@ -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.265 2003/08/17 23:43:25 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.266 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -262,6 +262,17 @@ _copyIndexScan(IndexScan *from)
|
|||||||
COPY_OIDLIST_FIELD(indxid);
|
COPY_OIDLIST_FIELD(indxid);
|
||||||
COPY_NODE_FIELD(indxqual);
|
COPY_NODE_FIELD(indxqual);
|
||||||
COPY_NODE_FIELD(indxqualorig);
|
COPY_NODE_FIELD(indxqualorig);
|
||||||
|
/* this can become COPY_NODE_FIELD when intlists are normal objects: */
|
||||||
|
{
|
||||||
|
List *newstrat = NIL;
|
||||||
|
List *tmp;
|
||||||
|
|
||||||
|
foreach(tmp, from->indxstrategy)
|
||||||
|
{
|
||||||
|
newstrat = lappend(newstrat, listCopy(lfirst(tmp)));
|
||||||
|
}
|
||||||
|
newnode->indxstrategy = newstrat;
|
||||||
|
}
|
||||||
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.218 2003/08/17 23:43:26 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.219 2003/11/09 21:30:36 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*
|
||||||
@ -336,6 +336,16 @@ _outIndexScan(StringInfo str, IndexScan *node)
|
|||||||
WRITE_OIDLIST_FIELD(indxid);
|
WRITE_OIDLIST_FIELD(indxid);
|
||||||
WRITE_NODE_FIELD(indxqual);
|
WRITE_NODE_FIELD(indxqual);
|
||||||
WRITE_NODE_FIELD(indxqualorig);
|
WRITE_NODE_FIELD(indxqualorig);
|
||||||
|
/* this can become WRITE_NODE_FIELD when intlists are normal objects: */
|
||||||
|
{
|
||||||
|
List *tmp;
|
||||||
|
|
||||||
|
appendStringInfo(str, " :indxstrategy ");
|
||||||
|
foreach(tmp, node->indxstrategy)
|
||||||
|
{
|
||||||
|
_outIntList(str, lfirst(tmp));
|
||||||
|
}
|
||||||
|
}
|
||||||
WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
|
WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.157 2003/08/27 12:44:12 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.158 2003/11/09 21:30:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -62,11 +62,14 @@ static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path,
|
|||||||
Plan *outer_plan, Plan *inner_plan);
|
Plan *outer_plan, Plan *inner_plan);
|
||||||
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);
|
||||||
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 **recheck_quals);
|
List **fixed_quals,
|
||||||
|
List **recheck_quals,
|
||||||
|
List **strategy);
|
||||||
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);
|
||||||
@ -77,7 +80,7 @@ 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,
|
||||||
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);
|
||||||
@ -700,6 +703,7 @@ create_indexscan_plan(Query *root,
|
|||||||
Expr *indxqual_or_expr = NULL;
|
Expr *indxqual_or_expr = NULL;
|
||||||
List *fixed_indxqual;
|
List *fixed_indxqual;
|
||||||
List *recheck_indxqual;
|
List *recheck_indxqual;
|
||||||
|
List *indxstrategy;
|
||||||
FastList indexids;
|
FastList indexids;
|
||||||
List *ixinfo;
|
List *ixinfo;
|
||||||
IndexScan *scan_plan;
|
IndexScan *scan_plan;
|
||||||
@ -766,7 +770,8 @@ create_indexscan_plan(Query *root,
|
|||||||
* pass also looks for "lossy" operators.
|
* pass also looks for "lossy" operators.
|
||||||
*/
|
*/
|
||||||
fix_indxqual_references(indxqual, best_path,
|
fix_indxqual_references(indxqual, best_path,
|
||||||
&fixed_indxqual, &recheck_indxqual);
|
&fixed_indxqual, &recheck_indxqual,
|
||||||
|
&indxstrategy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there were any "lossy" operators, need to add back the
|
* If there were any "lossy" operators, need to add back the
|
||||||
@ -798,6 +803,7 @@ create_indexscan_plan(Query *root,
|
|||||||
FastListValue(&indexids),
|
FastListValue(&indexids),
|
||||||
fixed_indxqual,
|
fixed_indxqual,
|
||||||
indxqual,
|
indxqual,
|
||||||
|
indxstrategy,
|
||||||
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);
|
||||||
@ -1134,7 +1140,7 @@ create_hashjoin_plan(Query *root,
|
|||||||
* Adjust indexqual clauses to the form the executor's indexqual
|
* Adjust indexqual clauses to the form the executor's indexqual
|
||||||
* machinery needs, and check for recheckable (lossy) index conditions.
|
* machinery needs, and check for recheckable (lossy) index conditions.
|
||||||
*
|
*
|
||||||
* We have three tasks here:
|
* We have four tasks here:
|
||||||
* * Index keys must be represented by Var nodes with varattno set to the
|
* * Index keys must be represented by Var nodes with varattno set to the
|
||||||
* index's attribute number, not the attribute number in the original rel.
|
* index's attribute number, not the attribute number in the original rel.
|
||||||
* * If the index key is on the right, commute the clause to put it on the
|
* * If the index key is on the right, commute the clause to put it on the
|
||||||
@ -1145,9 +1151,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
|
||||||
* This code used to be entirely bogus for multi-index scans. Now it keeps
|
* to the top-level operators of each index clause.
|
||||||
* track of which index applies to each subgroup of index qual clauses...
|
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -1160,10 +1165,13 @@ create_hashjoin_plan(Query *root,
|
|||||||
*
|
*
|
||||||
* recheck_indexquals similarly receives a full copy of whichever clauses
|
* recheck_indexquals similarly receives a full copy of whichever clauses
|
||||||
* need rechecking.
|
* need rechecking.
|
||||||
|
*
|
||||||
|
* indxstrategy receives a list of integer sublists of strategy numbers.
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
{
|
{
|
||||||
FastList fixed_quals;
|
FastList fixed_quals;
|
||||||
FastList recheck_quals;
|
FastList recheck_quals;
|
||||||
@ -1174,18 +1182,21 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
|
|||||||
|
|
||||||
FastListInit(&fixed_quals);
|
FastListInit(&fixed_quals);
|
||||||
FastListInit(&recheck_quals);
|
FastListInit(&recheck_quals);
|
||||||
|
*indxstrategy = NIL;
|
||||||
foreach(i, indexquals)
|
foreach(i, indexquals)
|
||||||
{
|
{
|
||||||
List *indexqual = lfirst(i);
|
List *indexqual = lfirst(i);
|
||||||
IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo);
|
IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo);
|
||||||
List *fixed_qual;
|
List *fixed_qual;
|
||||||
List *recheck_qual;
|
List *recheck_qual;
|
||||||
|
List *strategy;
|
||||||
|
|
||||||
fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
|
fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
|
||||||
&fixed_qual, &recheck_qual);
|
&fixed_qual, &recheck_qual, &strategy);
|
||||||
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);
|
||||||
|
|
||||||
ixinfo = lnext(ixinfo);
|
ixinfo = lnext(ixinfo);
|
||||||
}
|
}
|
||||||
@ -1199,18 +1210,21 @@ 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, and check for
|
* of the clause.) Also change the operator if necessary, check for
|
||||||
* lossy index behavior.
|
* lossy index behavior, and determine the operator's strategy number.
|
||||||
*
|
*
|
||||||
* Returns two lists: the list of fixed indexquals, and the list (usually
|
* Returns three lists: the list of fixed indexquals, the list (usually
|
||||||
* empty) of original clauses that must be rechecked as qpquals because
|
* empty) of original clauses that must be rechecked as qpquals because
|
||||||
* the index is lossy for this operator type.
|
* the index is lossy for this operator type, and the integer list of
|
||||||
|
* strategy numbers.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fix_indxqual_sublist(List *indexqual,
|
fix_indxqual_sublist(List *indexqual,
|
||||||
Relids baserelids, int baserelid,
|
Relids baserelids, int baserelid,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
List **fixed_quals, List **recheck_quals)
|
List **fixed_quals,
|
||||||
|
List **recheck_quals,
|
||||||
|
List **strategy)
|
||||||
{
|
{
|
||||||
FastList fixed_qual;
|
FastList fixed_qual;
|
||||||
FastList recheck_qual;
|
FastList recheck_qual;
|
||||||
@ -1218,14 +1232,18 @@ fix_indxqual_sublist(List *indexqual,
|
|||||||
|
|
||||||
FastListInit(&fixed_qual);
|
FastListInit(&fixed_qual);
|
||||||
FastListInit(&recheck_qual);
|
FastListInit(&recheck_qual);
|
||||||
|
*strategy = NIL;
|
||||||
foreach(i, indexqual)
|
foreach(i, indexqual)
|
||||||
{
|
{
|
||||||
OpExpr *clause = (OpExpr *) lfirst(i);
|
OpExpr *clause = (OpExpr *) lfirst(i);
|
||||||
OpExpr *newclause;
|
OpExpr *newclause;
|
||||||
Relids leftvarnos;
|
Relids leftvarnos;
|
||||||
Oid opclass;
|
Oid opclass;
|
||||||
|
int stratno;
|
||||||
|
bool recheck;
|
||||||
|
|
||||||
if (!IsA(clause, OpExpr) ||length(clause->args) != 2)
|
if (!IsA(clause, OpExpr) ||
|
||||||
|
length(clause->args) != 2)
|
||||||
elog(ERROR, "indexqual clause is not binary opclause");
|
elog(ERROR, "indexqual clause is not binary opclause");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1259,10 +1277,20 @@ fix_indxqual_sublist(List *indexqual,
|
|||||||
FastAppend(&fixed_qual, newclause);
|
FastAppend(&fixed_qual, newclause);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally, check to see if index is lossy for this operator. If
|
* Look up the operator in the operator class to get its strategy
|
||||||
* so, add (a copy of) original form of clause to recheck list.
|
* number and the recheck indicator. This also double-checks that
|
||||||
|
* we found an operator matching the index.
|
||||||
*/
|
*/
|
||||||
if (op_requires_recheck(newclause->opno, opclass))
|
get_op_opclass_properties(newclause->opno, opclass,
|
||||||
|
&stratno, &recheck);
|
||||||
|
|
||||||
|
*strategy = lappendi(*strategy, stratno);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If index is lossy for this operator, add (a copy of) original form
|
||||||
|
* of clause to recheck list.
|
||||||
|
*/
|
||||||
|
if (recheck)
|
||||||
FastAppend(&recheck_qual, copyObject((Node *) clause));
|
FastAppend(&recheck_qual, copyObject((Node *) clause));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1511,6 +1539,7 @@ make_indexscan(List *qptlist,
|
|||||||
List *indxid,
|
List *indxid,
|
||||||
List *indxqual,
|
List *indxqual,
|
||||||
List *indxqualorig,
|
List *indxqualorig,
|
||||||
|
List *indxstrategy,
|
||||||
ScanDirection indexscandir)
|
ScanDirection indexscandir)
|
||||||
{
|
{
|
||||||
IndexScan *node = makeNode(IndexScan);
|
IndexScan *node = makeNode(IndexScan);
|
||||||
@ -1525,6 +1554,7 @@ make_indexscan(List *qptlist,
|
|||||||
node->indxid = indxid;
|
node->indxid = indxid;
|
||||||
node->indxqual = indxqual;
|
node->indxqual = indxqual;
|
||||||
node->indxqualorig = indxqualorig;
|
node->indxqualorig = indxqualorig;
|
||||||
|
node->indxstrategy = indxstrategy;
|
||||||
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.87 2003/08/04 02:40:01 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.88 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#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"
|
||||||
@ -328,11 +329,10 @@ find_inheritance_children(Oid inhparent)
|
|||||||
if (!has_subclass(inhparent))
|
if (!has_subclass(inhparent))
|
||||||
return NIL;
|
return NIL;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key[0],
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_inherits_inhparent,
|
||||||
(AttrNumber) Anum_pg_inherits_inhparent,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) 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.161 2003/09/29 00:05:25 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.162 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1039,9 +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, 0x0, Anum_pg_inherits_inhrelid,
|
ScanKeyEntryInitialize(&skey, 0,
|
||||||
F_OIDEQ,
|
Anum_pg_inherits_inhrelid,
|
||||||
ObjectIdGetDatum(relid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relid), OIDOID);
|
||||||
|
|
||||||
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.56 2003/08/04 02:40:03 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.57 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#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"
|
||||||
@ -104,9 +105,10 @@ RemoveRewriteRuleById(Oid ruleOid)
|
|||||||
/*
|
/*
|
||||||
* Find the tuple for the target rule.
|
* Find the tuple for the target rule.
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(ruleOid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(ruleOid), OIDOID);
|
||||||
|
|
||||||
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.98 2003/08/04 02:40:03 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.99 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,7 +22,6 @@
|
|||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "access/nbtree.h"
|
|
||||||
#include "access/tuptoaster.h"
|
#include "access/tuptoaster.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
@ -203,11 +202,10 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
|||||||
|
|
||||||
Assert(PointerIsValid(obj_desc));
|
Assert(PointerIsValid(obj_desc));
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0],
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_largeobject_loid,
|
||||||
(AttrNumber) 1,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) 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);
|
||||||
@ -308,17 +306,15 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||||||
if (nbytes <= 0)
|
if (nbytes <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0],
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_largeobject_loid,
|
||||||
(AttrNumber) 1,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) F_OIDEQ,
|
ObjectIdGetDatum(obj_desc->id), OIDOID);
|
||||||
ObjectIdGetDatum(obj_desc->id));
|
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1],
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_largeobject_pageno,
|
||||||
(AttrNumber) 2,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
(RegProcedure) 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);
|
||||||
@ -417,17 +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],
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_largeobject_loid,
|
||||||
(AttrNumber) 1,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) F_OIDEQ,
|
ObjectIdGetDatum(obj_desc->id), OIDOID);
|
||||||
ObjectIdGetDatum(obj_desc->id));
|
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[1],
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_largeobject_pageno,
|
||||||
(AttrNumber) 2,
|
BTGreaterEqualStrategyNumber, F_INT4GE,
|
||||||
(RegProcedure) 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);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.82 2003/09/25 06:58:04 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.83 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -92,10 +92,10 @@ regprocin(PG_FUNCTION_ARGS)
|
|||||||
SysScanDesc sysscan;
|
SysScanDesc sysscan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_proc_proname,
|
Anum_pg_proc_proname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(pro_name_or_oid));
|
CStringGetDatum(pro_name_or_oid), NAMEOID);
|
||||||
|
|
||||||
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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_operator_oprname,
|
Anum_pg_operator_oprname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(opr_name_or_oid));
|
CStringGetDatum(opr_name_or_oid), NAMEOID);
|
||||||
|
|
||||||
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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(class_name_or_oid));
|
CStringGetDatum(class_name_or_oid), NAMEOID);
|
||||||
|
|
||||||
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], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
(AttrNumber) Anum_pg_type_typname,
|
Anum_pg_type_typname,
|
||||||
(RegProcedure) F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
CStringGetDatum(typ_name_or_oid));
|
CStringGetDatum(typ_name_or_oid), NAMEOID);
|
||||||
|
|
||||||
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.157 2003/10/04 18:22:59 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.158 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -488,9 +488,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
tgrel = heap_openr(TriggerRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(trigid));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(trigid), OIDOID);
|
||||||
|
|
||||||
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
@ -885,9 +886,10 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags)
|
|||||||
*/
|
*/
|
||||||
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
ObjectIdAttributeNumber, F_OIDEQ,
|
ObjectIdAttributeNumber,
|
||||||
ObjectIdGetDatum(constraintId));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(constraintId), OIDOID);
|
||||||
|
|
||||||
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
|
||||||
SnapshotNow, 1, skey);
|
SnapshotNow, 1, skey);
|
||||||
|
11
src/backend/utils/cache/catcache.c
vendored
11
src/backend/utils/cache/catcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.108 2003/08/04 02:40:06 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -937,6 +937,7 @@ CatalogCacheInitializeCache(CatCache *cache)
|
|||||||
for (i = 0; i < cache->cc_nkeys; ++i)
|
for (i = 0; i < cache->cc_nkeys; ++i)
|
||||||
{
|
{
|
||||||
Oid keytype;
|
Oid keytype;
|
||||||
|
RegProcedure eqfunc;
|
||||||
|
|
||||||
CatalogCacheInitializeCache_DEBUG2;
|
CatalogCacheInitializeCache_DEBUG2;
|
||||||
|
|
||||||
@ -951,7 +952,7 @@ CatalogCacheInitializeCache(CatCache *cache)
|
|||||||
|
|
||||||
GetCCHashEqFuncs(keytype,
|
GetCCHashEqFuncs(keytype,
|
||||||
&cache->cc_hashfunc[i],
|
&cache->cc_hashfunc[i],
|
||||||
&cache->cc_skey[i].sk_procedure);
|
&eqfunc);
|
||||||
|
|
||||||
cache->cc_isname[i] = (keytype == NAMEOID);
|
cache->cc_isname[i] = (keytype == NAMEOID);
|
||||||
|
|
||||||
@ -959,13 +960,17 @@ CatalogCacheInitializeCache(CatCache *cache)
|
|||||||
* Do equality-function lookup (we assume this won't need a
|
* Do equality-function lookup (we assume this won't need a
|
||||||
* catalog lookup for any supported type)
|
* catalog lookup for any supported type)
|
||||||
*/
|
*/
|
||||||
fmgr_info_cxt(cache->cc_skey[i].sk_procedure,
|
fmgr_info_cxt(eqfunc,
|
||||||
&cache->cc_skey[i].sk_func,
|
&cache->cc_skey[i].sk_func,
|
||||||
CacheMemoryContext);
|
CacheMemoryContext);
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
|
||||||
|
cache->cc_skey[i].sk_argtype = keytype;
|
||||||
|
|
||||||
CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p",
|
CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p",
|
||||||
cache->cc_relname,
|
cache->cc_relname,
|
||||||
i,
|
i,
|
||||||
|
20
src/backend/utils/cache/lsyscache.c
vendored
20
src/backend/utils/cache/lsyscache.c
vendored
@ -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.108 2003/10/04 18:22:59 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -53,21 +53,20 @@ op_in_opclass(Oid opno, Oid opclass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* op_requires_recheck
|
* get_op_opclass_properties
|
||||||
*
|
*
|
||||||
* Return t if operator 'opno' requires a recheck when used as a
|
* Get the operator's strategy number and recheck (lossy) flag
|
||||||
* member of opclass 'opclass' (ie, this opclass is lossy for this
|
* within the specified opclass.
|
||||||
* operator).
|
|
||||||
*
|
*
|
||||||
* Caller should already have verified that opno is a member of opclass,
|
* Caller should already have verified that opno is a member of opclass,
|
||||||
* therefore we raise an error if the tuple is not found.
|
* therefore we raise an error if the tuple is not found.
|
||||||
*/
|
*/
|
||||||
bool
|
void
|
||||||
op_requires_recheck(Oid opno, Oid opclass)
|
get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
|
int *strategy, bool *recheck)
|
||||||
{
|
{
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
Form_pg_amop amop_tup;
|
Form_pg_amop amop_tup;
|
||||||
bool result;
|
|
||||||
|
|
||||||
tp = SearchSysCache(AMOPOPID,
|
tp = SearchSysCache(AMOPOPID,
|
||||||
ObjectIdGetDatum(opno),
|
ObjectIdGetDatum(opno),
|
||||||
@ -77,10 +76,9 @@ op_requires_recheck(Oid opno, Oid opclass)
|
|||||||
elog(ERROR, "operator %u is not a member of opclass %u",
|
elog(ERROR, "operator %u is not a member of opclass %u",
|
||||||
opno, opclass);
|
opno, opclass);
|
||||||
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
|
||||||
|
*strategy = amop_tup->amopstrategy;
|
||||||
result = amop_tup->amopreqcheck;
|
*recheck = amop_tup->amopreqcheck;
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
241
src/backend/utils/cache/relcache.c
vendored
241
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.190 2003/09/25 06:58:05 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/istrat.h"
|
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
@ -69,6 +68,8 @@
|
|||||||
*/
|
*/
|
||||||
#define RELCACHE_INIT_FILENAME "pg_internal.init"
|
#define RELCACHE_INIT_FILENAME "pg_internal.init"
|
||||||
|
|
||||||
|
#define RELCACHE_INIT_FILEMAGIC 0x573261 /* version ID value */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
|
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
|
||||||
*/
|
*/
|
||||||
@ -260,6 +261,8 @@ do { \
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Special cache for opclass-related information
|
* Special cache for opclass-related information
|
||||||
|
*
|
||||||
|
* Note: only non-cross-type operators and support procs get cached
|
||||||
*/
|
*/
|
||||||
typedef struct opclasscacheent
|
typedef struct opclasscacheent
|
||||||
{
|
{
|
||||||
@ -268,7 +271,6 @@ typedef struct opclasscacheent
|
|||||||
StrategyNumber numStrats; /* max # of strategies (from pg_am) */
|
StrategyNumber numStrats; /* max # of strategies (from pg_am) */
|
||||||
StrategyNumber numSupport; /* max # of support procs (from pg_am) */
|
StrategyNumber numSupport; /* max # of support procs (from pg_am) */
|
||||||
Oid *operatorOids; /* strategy operators' OIDs */
|
Oid *operatorOids; /* strategy operators' OIDs */
|
||||||
RegProcedure *operatorProcs; /* strategy operators' procs */
|
|
||||||
RegProcedure *supportProcs; /* support procs */
|
RegProcedure *supportProcs; /* support procs */
|
||||||
} OpClassCacheEnt;
|
} OpClassCacheEnt;
|
||||||
|
|
||||||
@ -298,7 +300,6 @@ static void AttrDefaultFetch(Relation relation);
|
|||||||
static void CheckConstraintFetch(Relation relation);
|
static void CheckConstraintFetch(Relation relation);
|
||||||
static List *insert_ordered_oid(List *list, Oid datum);
|
static List *insert_ordered_oid(List *list, Oid datum);
|
||||||
static void IndexSupportInitialize(Form_pg_index iform,
|
static void IndexSupportInitialize(Form_pg_index iform,
|
||||||
IndexStrategy indexStrategy,
|
|
||||||
Oid *indexOperator,
|
Oid *indexOperator,
|
||||||
RegProcedure *indexSupport,
|
RegProcedure *indexSupport,
|
||||||
StrategyNumber maxStrategyNumber,
|
StrategyNumber maxStrategyNumber,
|
||||||
@ -337,8 +338,9 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
|
|||||||
case INFO_RELID:
|
case INFO_RELID:
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
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;
|
||||||
@ -346,12 +348,14 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
|
|||||||
case INFO_RELNAME:
|
case INFO_RELNAME:
|
||||||
ScanKeyEntryInitialize(&key[0], 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
F_NAMEEQ,
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
NameGetDatum(buildinfo.i.info_name));
|
NameGetDatum(buildinfo.i.info_name),
|
||||||
|
NAMEOID);
|
||||||
ScanKeyEntryInitialize(&key[1], 0,
|
ScanKeyEntryInitialize(&key[1], 0,
|
||||||
Anum_pg_class_relnamespace,
|
Anum_pg_class_relnamespace,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(PG_CATALOG_NAMESPACE));
|
ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
|
||||||
|
OIDOID);
|
||||||
nkeys = 2;
|
nkeys = 2;
|
||||||
indexRelname = ClassNameNspIndex;
|
indexRelname = ClassNameNspIndex;
|
||||||
break;
|
break;
|
||||||
@ -481,12 +485,13 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&skey[0], 0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_attribute_attrelid,
|
Anum_pg_attribute_attrelid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
ObjectIdGetDatum(RelationGetRelid(relation)),
|
||||||
|
OIDOID);
|
||||||
ScanKeyEntryInitialize(&skey[1], 0,
|
ScanKeyEntryInitialize(&skey[1], 0,
|
||||||
Anum_pg_attribute_attnum,
|
Anum_pg_attribute_attnum,
|
||||||
F_INT2GT,
|
BTGreaterStrategyNumber, F_INT2GT,
|
||||||
Int16GetDatum(0));
|
Int16GetDatum(0), INT2OID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@ -531,14 +536,10 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
if (attp->atthasdef)
|
if (attp->atthasdef)
|
||||||
{
|
{
|
||||||
if (attrdef == NULL)
|
if (attrdef == NULL)
|
||||||
{
|
|
||||||
attrdef = (AttrDefault *)
|
attrdef = (AttrDefault *)
|
||||||
MemoryContextAlloc(CacheMemoryContext,
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
relation->rd_rel->relnatts *
|
relation->rd_rel->relnatts *
|
||||||
sizeof(AttrDefault));
|
sizeof(AttrDefault));
|
||||||
MemSet(attrdef, 0,
|
|
||||||
relation->rd_rel->relnatts * sizeof(AttrDefault));
|
|
||||||
}
|
|
||||||
attrdef[ndef].adnum = attp->attnum;
|
attrdef[ndef].adnum = attp->attnum;
|
||||||
attrdef[ndef].adbin = NULL;
|
attrdef[ndef].adbin = NULL;
|
||||||
ndef++;
|
ndef++;
|
||||||
@ -605,9 +606,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
{
|
{
|
||||||
constr->num_check = relation->rd_rel->relchecks;
|
constr->num_check = relation->rd_rel->relchecks;
|
||||||
constr->check = (ConstrCheck *)
|
constr->check = (ConstrCheck *)
|
||||||
MemoryContextAlloc(CacheMemoryContext,
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
constr->num_check * sizeof(ConstrCheck));
|
constr->num_check * sizeof(ConstrCheck));
|
||||||
MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
|
|
||||||
CheckConstraintFetch(relation);
|
CheckConstraintFetch(relation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -675,8 +675,9 @@ RelationBuildRuleLock(Relation relation)
|
|||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_rewrite_ev_class,
|
Anum_pg_rewrite_ev_class,
|
||||||
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
|
||||||
@ -950,7 +951,6 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
Form_pg_am aform;
|
Form_pg_am aform;
|
||||||
MemoryContext indexcxt;
|
MemoryContext indexcxt;
|
||||||
MemoryContext oldcontext;
|
MemoryContext oldcontext;
|
||||||
IndexStrategy strategy;
|
|
||||||
Oid *operator;
|
Oid *operator;
|
||||||
RegProcedure *support;
|
RegProcedure *support;
|
||||||
FmgrInfo *supportinfo;
|
FmgrInfo *supportinfo;
|
||||||
@ -1016,33 +1016,20 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
* Allocate arrays to hold data
|
* Allocate arrays to hold data
|
||||||
*/
|
*/
|
||||||
if (amstrategies > 0)
|
if (amstrategies > 0)
|
||||||
{
|
|
||||||
int noperators = natts * amstrategies;
|
|
||||||
Size stratSize;
|
|
||||||
|
|
||||||
stratSize = AttributeNumberGetIndexStrategySize(natts, amstrategies);
|
|
||||||
strategy = (IndexStrategy) MemoryContextAlloc(indexcxt, stratSize);
|
|
||||||
MemSet(strategy, 0, stratSize);
|
|
||||||
operator = (Oid *)
|
operator = (Oid *)
|
||||||
MemoryContextAlloc(indexcxt, noperators * sizeof(Oid));
|
MemoryContextAllocZero(indexcxt,
|
||||||
MemSet(operator, 0, noperators * sizeof(Oid));
|
natts * amstrategies * sizeof(Oid));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
strategy = NULL;
|
|
||||||
operator = NULL;
|
operator = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (amsupport > 0)
|
if (amsupport > 0)
|
||||||
{
|
{
|
||||||
int nsupport = natts * amsupport;
|
int nsupport = natts * amsupport;
|
||||||
|
|
||||||
support = (RegProcedure *)
|
support = (RegProcedure *)
|
||||||
MemoryContextAlloc(indexcxt, nsupport * sizeof(RegProcedure));
|
MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
|
||||||
MemSet(support, 0, nsupport * sizeof(RegProcedure));
|
|
||||||
supportinfo = (FmgrInfo *)
|
supportinfo = (FmgrInfo *)
|
||||||
MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
|
MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
|
||||||
MemSet(supportinfo, 0, nsupport * sizeof(FmgrInfo));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1050,17 +1037,16 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
supportinfo = NULL;
|
supportinfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
relation->rd_istrat = strategy;
|
|
||||||
relation->rd_operator = operator;
|
relation->rd_operator = operator;
|
||||||
relation->rd_support = support;
|
relation->rd_support = support;
|
||||||
relation->rd_supportinfo = supportinfo;
|
relation->rd_supportinfo = supportinfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill the strategy map and the support RegProcedure arrays.
|
* Fill the operator and support procedure OID arrays.
|
||||||
* (supportinfo is left as zeroes, and is filled on-the-fly when used)
|
* (supportinfo is left as zeroes, and is filled on-the-fly when used)
|
||||||
*/
|
*/
|
||||||
IndexSupportInitialize(relation->rd_index,
|
IndexSupportInitialize(relation->rd_index,
|
||||||
strategy, operator, support,
|
operator, support,
|
||||||
amstrategies, amsupport, natts);
|
amstrategies, amsupport, natts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1072,11 +1058,11 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* IndexSupportInitialize
|
* IndexSupportInitialize
|
||||||
* Initializes an index strategy and associated support procedures,
|
* Initializes an index's cached lists of operators and support procs,
|
||||||
* given the index's pg_index tuple.
|
* given the index's pg_index tuple.
|
||||||
*
|
*
|
||||||
* Data is returned into *indexStrategy, *indexOperator, and *indexSupport,
|
* Data is returned into *indexOperator and *indexSupport, which are arrays
|
||||||
* all of which are objects allocated by the caller.
|
* allocated by the caller.
|
||||||
*
|
*
|
||||||
* The caller also passes maxStrategyNumber, maxSupportNumber, and
|
* The caller also passes maxStrategyNumber, maxSupportNumber, and
|
||||||
* maxAttributeNumber, since these indicate the size of the arrays
|
* maxAttributeNumber, since these indicate the size of the arrays
|
||||||
@ -1086,7 +1072,6 @@ RelationInitIndexAccessInfo(Relation relation)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
IndexSupportInitialize(Form_pg_index iform,
|
IndexSupportInitialize(Form_pg_index iform,
|
||||||
IndexStrategy indexStrategy,
|
|
||||||
Oid *indexOperator,
|
Oid *indexOperator,
|
||||||
RegProcedure *indexSupport,
|
RegProcedure *indexSupport,
|
||||||
StrategyNumber maxStrategyNumber,
|
StrategyNumber maxStrategyNumber,
|
||||||
@ -1095,8 +1080,6 @@ IndexSupportInitialize(Form_pg_index iform,
|
|||||||
{
|
{
|
||||||
int attIndex;
|
int attIndex;
|
||||||
|
|
||||||
maxStrategyNumber = AMStrategies(maxStrategyNumber);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX note that the following assumes the INDEX tuple is well formed
|
* XXX note that the following assumes the INDEX tuple is well formed
|
||||||
* and that the *key and *class are 0 terminated.
|
* and that the *key and *class are 0 terminated.
|
||||||
@ -1113,52 +1096,15 @@ IndexSupportInitialize(Form_pg_index iform,
|
|||||||
maxStrategyNumber,
|
maxStrategyNumber,
|
||||||
maxSupportNumber);
|
maxSupportNumber);
|
||||||
|
|
||||||
/* load the strategy information for the index operators */
|
/* copy cached data into relcache entry */
|
||||||
if (maxStrategyNumber > 0)
|
if (maxStrategyNumber > 0)
|
||||||
{
|
memcpy(&indexOperator[attIndex * maxStrategyNumber],
|
||||||
StrategyMap map;
|
opcentry->operatorOids,
|
||||||
Oid *opers;
|
maxStrategyNumber * sizeof(Oid));
|
||||||
StrategyNumber strategy;
|
|
||||||
|
|
||||||
map = IndexStrategyGetStrategyMap(indexStrategy,
|
|
||||||
maxStrategyNumber,
|
|
||||||
attIndex + 1);
|
|
||||||
opers = &indexOperator[attIndex * maxStrategyNumber];
|
|
||||||
|
|
||||||
for (strategy = 0; strategy < maxStrategyNumber; strategy++)
|
|
||||||
{
|
|
||||||
ScanKey mapentry;
|
|
||||||
|
|
||||||
mapentry = StrategyMapGetScanKeyEntry(map, strategy + 1);
|
|
||||||
if (RegProcedureIsValid(opcentry->operatorProcs[strategy]))
|
|
||||||
{
|
|
||||||
MemSet(mapentry, 0, sizeof(*mapentry));
|
|
||||||
mapentry->sk_flags = 0;
|
|
||||||
mapentry->sk_procedure = opcentry->operatorProcs[strategy];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mark mapentry->sk_func invalid, until and unless
|
|
||||||
* someone sets it up.
|
|
||||||
*/
|
|
||||||
mapentry->sk_func.fn_oid = InvalidOid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ScanKeyEntrySetIllegal(mapentry);
|
|
||||||
opers[strategy] = opcentry->operatorOids[strategy];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if support routines exist for this access method, load them */
|
|
||||||
if (maxSupportNumber > 0)
|
if (maxSupportNumber > 0)
|
||||||
{
|
memcpy(&indexSupport[attIndex * maxSupportNumber],
|
||||||
RegProcedure *procs;
|
opcentry->supportProcs,
|
||||||
StrategyNumber support;
|
maxSupportNumber * sizeof(RegProcedure));
|
||||||
|
|
||||||
procs = &indexSupport[attIndex * maxSupportNumber];
|
|
||||||
|
|
||||||
for (support = 0; support < maxSupportNumber; ++support)
|
|
||||||
procs[support] = opcentry->supportProcs[support];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,29 +1177,16 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
opcentry->numSupport = numSupport;
|
opcentry->numSupport = numSupport;
|
||||||
|
|
||||||
if (numStrats > 0)
|
if (numStrats > 0)
|
||||||
{
|
|
||||||
opcentry->operatorOids = (Oid *)
|
opcentry->operatorOids = (Oid *)
|
||||||
MemoryContextAlloc(CacheMemoryContext,
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
numStrats * sizeof(Oid));
|
numStrats * sizeof(Oid));
|
||||||
MemSet(opcentry->operatorOids, 0, numStrats * sizeof(Oid));
|
|
||||||
opcentry->operatorProcs = (RegProcedure *)
|
|
||||||
MemoryContextAlloc(CacheMemoryContext,
|
|
||||||
numStrats * sizeof(RegProcedure));
|
|
||||||
MemSet(opcentry->operatorProcs, 0, numStrats * sizeof(RegProcedure));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
opcentry->operatorOids = NULL;
|
opcentry->operatorOids = NULL;
|
||||||
opcentry->operatorProcs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numSupport > 0)
|
if (numSupport > 0)
|
||||||
{
|
|
||||||
opcentry->supportProcs = (RegProcedure *)
|
opcentry->supportProcs = (RegProcedure *)
|
||||||
MemoryContextAlloc(CacheMemoryContext,
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
numSupport * sizeof(RegProcedure));
|
numSupport * sizeof(RegProcedure));
|
||||||
MemSet(opcentry->supportProcs, 0, numSupport * sizeof(RegProcedure));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
opcentry->supportProcs = NULL;
|
opcentry->supportProcs = NULL;
|
||||||
|
|
||||||
@ -1273,8 +1206,9 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_amop_amopclaid,
|
Anum_pg_amop_amopclaid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(operatorClassOid));
|
ObjectIdGetDatum(operatorClassOid),
|
||||||
|
OIDOID);
|
||||||
pg_amop_desc = heap_openr(AccessMethodOperatorRelationName,
|
pg_amop_desc = heap_openr(AccessMethodOperatorRelationName,
|
||||||
AccessShareLock);
|
AccessShareLock);
|
||||||
pg_amop_scan = systable_beginscan(pg_amop_desc,
|
pg_amop_scan = systable_beginscan(pg_amop_desc,
|
||||||
@ -1293,8 +1227,6 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
amopform->amopstrategy, operatorClassOid);
|
amopform->amopstrategy, operatorClassOid);
|
||||||
opcentry->operatorOids[amopform->amopstrategy - 1] =
|
opcentry->operatorOids[amopform->amopstrategy - 1] =
|
||||||
amopform->amopopr;
|
amopform->amopopr;
|
||||||
opcentry->operatorProcs[amopform->amopstrategy - 1] =
|
|
||||||
get_opcode(amopform->amopopr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(pg_amop_scan);
|
systable_endscan(pg_amop_scan);
|
||||||
@ -1308,8 +1240,9 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
{
|
{
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_amproc_amopclaid,
|
Anum_pg_amproc_amopclaid,
|
||||||
F_OIDEQ,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
ObjectIdGetDatum(operatorClassOid));
|
ObjectIdGetDatum(operatorClassOid),
|
||||||
|
OIDOID);
|
||||||
pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName,
|
pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName,
|
||||||
AccessShareLock);
|
AccessShareLock);
|
||||||
pg_amproc_scan = systable_beginscan(pg_amproc_desc,
|
pg_amproc_scan = systable_beginscan(pg_amproc_desc,
|
||||||
@ -2550,11 +2483,11 @@ AttrDefaultFetch(Relation relation)
|
|||||||
int found;
|
int found;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey,
|
ScanKeyEntryInitialize(&skey, 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_attrdef_adrelid,
|
||||||
(AttrNumber) Anum_pg_attrdef_adrelid,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) 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,
|
||||||
@ -2617,9 +2550,11 @@ CheckConstraintFetch(Relation relation)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_constraint_conrelid, F_OIDEQ,
|
Anum_pg_constraint_conrelid,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
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,
|
||||||
@ -2707,11 +2642,11 @@ 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,
|
ScanKeyEntryInitialize(&skey, 0,
|
||||||
(bits16) 0x0,
|
Anum_pg_index_indrelid,
|
||||||
(AttrNumber) Anum_pg_index_indrelid,
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
(RegProcedure) 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,
|
||||||
@ -2988,7 +2923,8 @@ load_relcache_init_file(void)
|
|||||||
num_rels,
|
num_rels,
|
||||||
max_rels,
|
max_rels,
|
||||||
nailed_rels,
|
nailed_rels,
|
||||||
nailed_indexes;
|
nailed_indexes,
|
||||||
|
magic;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
snprintf(initfilename, sizeof(initfilename), "%s/%s",
|
snprintf(initfilename, sizeof(initfilename), "%s/%s",
|
||||||
@ -3012,6 +2948,12 @@ load_relcache_init_file(void)
|
|||||||
nailed_rels = nailed_indexes = 0;
|
nailed_rels = nailed_indexes = 0;
|
||||||
initFileRelationIds = NIL;
|
initFileRelationIds = NIL;
|
||||||
|
|
||||||
|
/* check for correct magic number (compatible version) */
|
||||||
|
if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
|
||||||
|
goto read_failed;
|
||||||
|
if (magic != RELCACHE_INIT_FILEMAGIC)
|
||||||
|
goto read_failed;
|
||||||
|
|
||||||
for (relno = 0;; relno++)
|
for (relno = 0;; relno++)
|
||||||
{
|
{
|
||||||
Size len;
|
Size len;
|
||||||
@ -3088,11 +3030,9 @@ load_relcache_init_file(void)
|
|||||||
{
|
{
|
||||||
Form_pg_am am;
|
Form_pg_am am;
|
||||||
MemoryContext indexcxt;
|
MemoryContext indexcxt;
|
||||||
IndexStrategy strat;
|
|
||||||
Oid *operator;
|
Oid *operator;
|
||||||
RegProcedure *support;
|
RegProcedure *support;
|
||||||
int nstrategies,
|
int nsupport;
|
||||||
nsupport;
|
|
||||||
|
|
||||||
/* Count nailed indexes to ensure we have 'em all */
|
/* Count nailed indexes to ensure we have 'em all */
|
||||||
if (rel->rd_isnailed)
|
if (rel->rd_isnailed)
|
||||||
@ -3131,21 +3071,6 @@ load_relcache_init_file(void)
|
|||||||
ALLOCSET_SMALL_MAXSIZE);
|
ALLOCSET_SMALL_MAXSIZE);
|
||||||
rel->rd_indexcxt = indexcxt;
|
rel->rd_indexcxt = indexcxt;
|
||||||
|
|
||||||
/* next, read the index strategy map */
|
|
||||||
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
|
||||||
goto read_failed;
|
|
||||||
|
|
||||||
strat = (IndexStrategy) MemoryContextAlloc(indexcxt, len);
|
|
||||||
if ((nread = fread(strat, 1, len, fp)) != len)
|
|
||||||
goto read_failed;
|
|
||||||
|
|
||||||
/* have to invalidate any FmgrInfo data in the strategy maps */
|
|
||||||
nstrategies = am->amstrategies * relform->relnatts;
|
|
||||||
for (i = 0; i < nstrategies; i++)
|
|
||||||
strat->strategyMapData[i].entry[0].sk_func.fn_oid = InvalidOid;
|
|
||||||
|
|
||||||
rel->rd_istrat = strat;
|
|
||||||
|
|
||||||
/* next, read the vector of operator OIDs */
|
/* next, read the vector of operator OIDs */
|
||||||
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
||||||
goto read_failed;
|
goto read_failed;
|
||||||
@ -3168,8 +3093,7 @@ load_relcache_init_file(void)
|
|||||||
/* add a zeroed support-fmgr-info vector */
|
/* add a zeroed support-fmgr-info vector */
|
||||||
nsupport = relform->relnatts * am->amsupport;
|
nsupport = relform->relnatts * am->amsupport;
|
||||||
rel->rd_supportinfo = (FmgrInfo *)
|
rel->rd_supportinfo = (FmgrInfo *)
|
||||||
MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
|
MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
|
||||||
MemSet(rel->rd_supportinfo, 0, nsupport * sizeof(FmgrInfo));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3181,7 +3105,6 @@ load_relcache_init_file(void)
|
|||||||
Assert(rel->rd_indextuple == NULL);
|
Assert(rel->rd_indextuple == NULL);
|
||||||
Assert(rel->rd_am == NULL);
|
Assert(rel->rd_am == NULL);
|
||||||
Assert(rel->rd_indexcxt == NULL);
|
Assert(rel->rd_indexcxt == NULL);
|
||||||
Assert(rel->rd_istrat == NULL);
|
|
||||||
Assert(rel->rd_operator == NULL);
|
Assert(rel->rd_operator == NULL);
|
||||||
Assert(rel->rd_support == NULL);
|
Assert(rel->rd_support == NULL);
|
||||||
Assert(rel->rd_supportinfo == NULL);
|
Assert(rel->rd_supportinfo == NULL);
|
||||||
@ -3277,6 +3200,7 @@ write_relcache_init_file(void)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
char tempfilename[MAXPGPATH];
|
char tempfilename[MAXPGPATH];
|
||||||
char finalfilename[MAXPGPATH];
|
char finalfilename[MAXPGPATH];
|
||||||
|
int magic;
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
RelIdCacheEnt *idhentry;
|
RelIdCacheEnt *idhentry;
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
@ -3309,6 +3233,14 @@ write_relcache_init_file(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a magic number to serve as a file version identifier. We can
|
||||||
|
* change the magic number whenever the relcache layout changes.
|
||||||
|
*/
|
||||||
|
magic = RELCACHE_INIT_FILEMAGIC;
|
||||||
|
if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
|
||||||
|
elog(FATAL, "could not write init file");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write all the reldescs (in no particular order).
|
* Write all the reldescs (in no particular order).
|
||||||
*/
|
*/
|
||||||
@ -3375,15 +3307,6 @@ write_relcache_init_file(void)
|
|||||||
if (fwrite(am, 1, len, fp) != len)
|
if (fwrite(am, 1, len, fp) != len)
|
||||||
elog(FATAL, "could not write init file");
|
elog(FATAL, "could not write init file");
|
||||||
|
|
||||||
/* next, write the index strategy map */
|
|
||||||
len = AttributeNumberGetIndexStrategySize(relform->relnatts,
|
|
||||||
am->amstrategies);
|
|
||||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
|
||||||
elog(FATAL, "could not write init file");
|
|
||||||
|
|
||||||
if (fwrite(rel->rd_istrat, 1, len, fp) != len)
|
|
||||||
elog(FATAL, "could not write init file");
|
|
||||||
|
|
||||||
/* next, write the vector of operator OIDs */
|
/* next, write the vector of operator OIDs */
|
||||||
len = relform->relnatts * (am->amstrategies * sizeof(Oid));
|
len = relform->relnatts * (am->amstrategies * sizeof(Oid));
|
||||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||||
|
9
src/backend/utils/cache/typcache.c
vendored
9
src/backend/utils/cache/typcache.c
vendored
@ -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.1 2003/08/17 19:58:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.2 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -248,9 +248,10 @@ lookup_default_opclass(Oid type_id, Oid am_id)
|
|||||||
*/
|
*/
|
||||||
rel = heap_openr(OperatorClassRelationName, AccessShareLock);
|
rel = heap_openr(OperatorClassRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
ScanKeyEntryInitialize(&skey[0], 0,
|
||||||
Anum_pg_opclass_opcamid, F_OIDEQ,
|
Anum_pg_opclass_opcamid,
|
||||||
ObjectIdGetDatum(am_id));
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(am_id), OIDOID);
|
||||||
|
|
||||||
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.127 2003/09/25 06:58:05 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.128 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#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"
|
||||||
@ -91,8 +92,10 @@ ReverifyMyDatabase(const char *name)
|
|||||||
*/
|
*/
|
||||||
pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
|
pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
F_NAMEEQ, NameGetDatum(name));
|
Anum_pg_database_datname,
|
||||||
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
NameGetDatum(name), NAMEOID);
|
||||||
|
|
||||||
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.37 2003/08/17 19:58:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.38 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -471,11 +471,16 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
|||||||
SelectSortFunction(sortOperators[i], &sortFunction,
|
SelectSortFunction(sortOperators[i], &sortFunction,
|
||||||
&state->sortFnKinds[i]);
|
&state->sortFnKinds[i]);
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&state->scanKeys[i],
|
/*
|
||||||
0x0,
|
* We needn't fill in sk_strategy or sk_argtype since these scankeys
|
||||||
|
* will never be passed to an index.
|
||||||
|
*/
|
||||||
|
ScanKeyEntryInitialize(&state->scanKeys[i], 0,
|
||||||
attNums[i],
|
attNums[i],
|
||||||
|
InvalidStrategy,
|
||||||
sortFunction,
|
sortFunction,
|
||||||
(Datum) 0);
|
(Datum) 0,
|
||||||
|
InvalidOid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@ -1929,13 +1934,8 @@ comparetup_heap(Tuplesortstate *state, const void *a, const void *b)
|
|||||||
datum1, isnull1,
|
datum1, isnull1,
|
||||||
datum2, isnull2);
|
datum2, isnull2);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
{
|
|
||||||
/* dead code? SK_COMMUTE can't actually be set here, can it? */
|
|
||||||
if (scanKey->sk_flags & SK_COMMUTE)
|
|
||||||
compare = -compare;
|
|
||||||
return compare;
|
return compare;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 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: gist.h,v 1.37 2003/08/04 02:40:10 momjian Exp $
|
* $Id: gist.h,v 1.38 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -175,8 +175,6 @@ extern void freeGISTstate(GISTSTATE *giststate);
|
|||||||
extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
|
extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
|
||||||
Datum k, Relation r, Page pg, OffsetNumber o,
|
Datum k, Relation r, Page pg, OffsetNumber o,
|
||||||
int b, bool l, bool isNull);
|
int b, bool l, bool isNull);
|
||||||
extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber,
|
|
||||||
RegProcedure);
|
|
||||||
|
|
||||||
extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
|
extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
|
||||||
extern void gist_undo(XLogRecPtr lsn, XLogRecord *record);
|
extern void gist_undo(XLogRecPtr lsn, XLogRecord *record);
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* istrat.h
|
|
||||||
* POSTGRES index strategy definitions.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
* $Id: istrat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#ifndef ISTRAT_H
|
|
||||||
#define ISTRAT_H
|
|
||||||
|
|
||||||
#include "utils/rel.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyNumberIsValid
|
|
||||||
* True iff the strategy number is valid.
|
|
||||||
*/
|
|
||||||
#define StrategyNumberIsValid(strategyNumber) \
|
|
||||||
((bool) ((strategyNumber) != InvalidStrategy))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyNumberIsInBounds
|
|
||||||
* True iff strategy number is within given bounds.
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Assumes StrategyNumber is an unsigned type.
|
|
||||||
* Assumes the bounded interval to be (0,max].
|
|
||||||
*/
|
|
||||||
#define StrategyNumberIsInBounds(strategyNumber, maxStrategyNumber) \
|
|
||||||
((bool)(InvalidStrategy < (strategyNumber) && \
|
|
||||||
(strategyNumber) <= (maxStrategyNumber)))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyMapIsValid
|
|
||||||
* True iff the index strategy mapping is valid.
|
|
||||||
*/
|
|
||||||
#define StrategyMapIsValid(map) PointerIsValid(map)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IndexStrategyIsValid
|
|
||||||
* True iff the index strategy is valid.
|
|
||||||
*/
|
|
||||||
#define IndexStrategyIsValid(s) PointerIsValid(s)
|
|
||||||
|
|
||||||
extern ScanKey StrategyMapGetScanKeyEntry(StrategyMap map,
|
|
||||||
StrategyNumber strategyNumber);
|
|
||||||
extern StrategyMap IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
|
|
||||||
StrategyNumber maxStrategyNum, AttrNumber attrNum);
|
|
||||||
|
|
||||||
extern Size AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
|
|
||||||
StrategyNumber maxStrategyNumber);
|
|
||||||
extern StrategyNumber RelationGetStrategy(Relation relation,
|
|
||||||
AttrNumber attributeNumber, StrategyEvaluation evaluation,
|
|
||||||
RegProcedure procedure);
|
|
||||||
|
|
||||||
#endif /* ISTRAT_H */
|
|
@ -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.71 2003/09/29 23:40:26 tgl Exp $
|
* $Id: nbtree.h,v 1.72 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -340,16 +340,10 @@ typedef struct xl_btree_newpage
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operator strategy numbers -- ordering of these is <, <=, =, >=, >
|
* Operator strategy numbers for B-tree have been moved to access/skey.h,
|
||||||
|
* because many places need to use them in ScanKeyEntryInitialize() calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BTLessStrategyNumber 1
|
|
||||||
#define BTLessEqualStrategyNumber 2
|
|
||||||
#define BTEqualStrategyNumber 3
|
|
||||||
#define BTGreaterEqualStrategyNumber 4
|
|
||||||
#define BTGreaterStrategyNumber 5
|
|
||||||
#define BTMaxStrategyNumber 5
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a new operator class is declared, we require that the user
|
* When a new operator class is declared, we require that the user
|
||||||
* supply us with an amproc procedure for determining whether, for
|
* supply us with an amproc procedure for determining whether, for
|
||||||
@ -479,12 +473,6 @@ extern bool _bt_first(IndexScanDesc scan, ScanDirection dir);
|
|||||||
extern bool _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
|
extern bool _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
|
||||||
extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost);
|
extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost);
|
||||||
|
|
||||||
/*
|
|
||||||
* prototypes for functions in nbtstrat.c
|
|
||||||
*/
|
|
||||||
extern StrategyNumber _bt_getstrat(Relation rel, AttrNumber attno,
|
|
||||||
RegProcedure proc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in nbtutils.c
|
* prototypes for functions in nbtutils.c
|
||||||
*/
|
*/
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
* 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: relscan.h,v 1.32 2003/08/04 02:40:10 momjian Exp $
|
* $Id: relscan.h,v 1.33 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef RELSCAN_H
|
#ifndef RELSCAN_H
|
||||||
#define RELSCAN_H
|
#define RELSCAN_H
|
||||||
|
|
||||||
|
#include "access/skey.h"
|
||||||
#include "utils/tqual.h"
|
#include "utils/tqual.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -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: rtree.h,v 1.30 2003/08/04 02:40:10 momjian Exp $
|
* $Id: rtree.h,v 1.31 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -132,7 +132,6 @@ extern void rtadjscans(Relation r, int op, BlockNumber blkno,
|
|||||||
extern void AtEOXact_rtree(void);
|
extern void AtEOXact_rtree(void);
|
||||||
|
|
||||||
/* rtstrat.c */
|
/* rtstrat.c */
|
||||||
extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
|
extern StrategyNumber RTMapToInternalOperator(StrategyNumber strat);
|
||||||
RegProcedure proc);
|
|
||||||
|
|
||||||
#endif /* RTREE_H */
|
#endif /* RTREE_H */
|
||||||
|
@ -7,10 +7,8 @@
|
|||||||
* 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.22 2003/08/04 02:40:10 momjian Exp $
|
* $Id: skey.h,v 1.23 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
* Note:
|
|
||||||
* Needs more accessor/assignment routines.
|
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef SKEY_H
|
#ifndef SKEY_H
|
||||||
@ -20,32 +18,77 @@
|
|||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Strategy numbers identify the semantics that particular operators have
|
||||||
|
* with respect to particular operator classes.
|
||||||
|
*/
|
||||||
|
typedef uint16 StrategyNumber;
|
||||||
|
|
||||||
|
#define InvalidStrategy ((StrategyNumber) 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We define the strategy numbers for B-tree indexes here, to avoid having
|
||||||
|
* to import access/nbtree.h into a lot of places that shouldn't need it.
|
||||||
|
*/
|
||||||
|
#define BTLessStrategyNumber 1
|
||||||
|
#define BTLessEqualStrategyNumber 2
|
||||||
|
#define BTEqualStrategyNumber 3
|
||||||
|
#define BTGreaterEqualStrategyNumber 4
|
||||||
|
#define BTGreaterStrategyNumber 5
|
||||||
|
|
||||||
|
#define BTMaxStrategyNumber 5
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A ScanKey represents the application of a comparison operator between
|
||||||
|
* a table or index column and a constant. When it's part of an array of
|
||||||
|
* ScanKeys, the comparison conditions are implicitly ANDed. The index
|
||||||
|
* column is the left argument of the operator, if it's a binary operator.
|
||||||
|
* (The data structure can support unary indexable operators too; in that
|
||||||
|
* case sk_argument would go unused. This is not currently implemented.)
|
||||||
|
*
|
||||||
|
* For an index scan, sk_strategy must be set correctly for the operator.
|
||||||
|
* When using a ScanKey in a heap scan, sk_strategy is not used and may be
|
||||||
|
* set to InvalidStrategy.
|
||||||
|
*
|
||||||
|
* Note: in some places, ScanKeys are used as a convenient representation
|
||||||
|
* 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
|
||||||
|
* returns something other than boolean.
|
||||||
|
*/
|
||||||
typedef struct ScanKeyData
|
typedef struct ScanKeyData
|
||||||
{
|
{
|
||||||
bits16 sk_flags; /* flags */
|
int sk_flags; /* flags, see below */
|
||||||
AttrNumber sk_attno; /* domain number */
|
AttrNumber sk_attno; /* table or index column number */
|
||||||
RegProcedure sk_procedure; /* procedure OID */
|
StrategyNumber sk_strategy; /* operator strategy number */
|
||||||
FmgrInfo sk_func; /* fmgr call info for procedure */
|
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;
|
||||||
|
|
||||||
/* ScanKeyData flags */
|
/* ScanKeyData sk_flags */
|
||||||
#define SK_ISNULL 0x1 /* sk_argument is NULL */
|
#define SK_ISNULL 0x0001 /* sk_argument is NULL */
|
||||||
#define SK_UNARY 0x2 /* unary function (currently unsupported) */
|
#define SK_UNARY 0x0002 /* unary operator (currently unsupported) */
|
||||||
#define SK_NEGATE 0x4 /* negate function result */
|
|
||||||
#define SK_COMMUTE 0x8 /* commute function (not fully supported) */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in access/common/scankey.c
|
* prototypes for functions in access/common/scankey.c
|
||||||
*/
|
*/
|
||||||
extern void ScanKeyEntrySetIllegal(ScanKey entry);
|
extern void ScanKeyEntryInitialize(ScanKey entry,
|
||||||
extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
|
int flags,
|
||||||
AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
|
AttrNumber attributeNumber,
|
||||||
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, bits16 flags,
|
StrategyNumber strategy,
|
||||||
AttrNumber attributeNumber, FmgrInfo *finfo,
|
RegProcedure procedure,
|
||||||
MemoryContext mcxt, Datum argument);
|
Datum argument,
|
||||||
|
Oid argtype);
|
||||||
|
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
||||||
|
int flags,
|
||||||
|
AttrNumber attributeNumber,
|
||||||
|
StrategyNumber strategy,
|
||||||
|
FmgrInfo *finfo,
|
||||||
|
Datum argument,
|
||||||
|
Oid argtype);
|
||||||
|
|
||||||
#endif /* SKEY_H */
|
#endif /* SKEY_H */
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* strat.h
|
|
||||||
* index strategy type definitions
|
|
||||||
* (separated out from original istrat.h to avoid circular refs)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
|
||||||
*
|
|
||||||
* $Id: strat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#ifndef STRAT_H
|
|
||||||
#define STRAT_H
|
|
||||||
|
|
||||||
#include "access/skey.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint16 StrategyNumber;
|
|
||||||
|
|
||||||
#define InvalidStrategy 0
|
|
||||||
|
|
||||||
typedef struct StrategyTransformMapData
|
|
||||||
{
|
|
||||||
StrategyNumber strategy[1]; /* VARIABLE LENGTH ARRAY */
|
|
||||||
} StrategyTransformMapData; /* VARIABLE LENGTH STRUCTURE */
|
|
||||||
|
|
||||||
typedef StrategyTransformMapData *StrategyTransformMap;
|
|
||||||
|
|
||||||
typedef struct StrategyOperatorData
|
|
||||||
{
|
|
||||||
StrategyNumber strategy;
|
|
||||||
bits16 flags; /* scan qualification flags, see skey.h */
|
|
||||||
} StrategyOperatorData;
|
|
||||||
|
|
||||||
typedef StrategyOperatorData *StrategyOperator;
|
|
||||||
|
|
||||||
typedef struct StrategyTermData
|
|
||||||
{ /* conjunctive term */
|
|
||||||
uint16 degree;
|
|
||||||
StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH ARRAY */
|
|
||||||
} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */
|
|
||||||
|
|
||||||
typedef StrategyTermData *StrategyTerm;
|
|
||||||
|
|
||||||
typedef struct StrategyExpressionData
|
|
||||||
{ /* disjunctive normal form */
|
|
||||||
StrategyTerm term[1]; /* VARIABLE LENGTH ARRAY */
|
|
||||||
} StrategyExpressionData; /* VARIABLE LENGTH STRUCTURE */
|
|
||||||
|
|
||||||
typedef StrategyExpressionData *StrategyExpression;
|
|
||||||
|
|
||||||
typedef struct StrategyEvaluationData
|
|
||||||
{
|
|
||||||
StrategyNumber maxStrategy;
|
|
||||||
/* each of these must point to an array of maxStrategy elements: */
|
|
||||||
StrategyTransformMap negateTransform;
|
|
||||||
StrategyTransformMap commuteTransform;
|
|
||||||
StrategyTransformMap negateCommuteTransform;
|
|
||||||
StrategyExpression *expression;
|
|
||||||
} StrategyEvaluationData;
|
|
||||||
|
|
||||||
typedef StrategyEvaluationData *StrategyEvaluation;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* StrategyTransformMapIsValid
|
|
||||||
* Returns true iff strategy transformation map is valid.
|
|
||||||
*/
|
|
||||||
#define StrategyTransformMapIsValid(transform) PointerIsValid(transform)
|
|
||||||
|
|
||||||
|
|
||||||
#define AMStrategies(foo) (foo)
|
|
||||||
|
|
||||||
typedef struct StrategyMapData
|
|
||||||
{
|
|
||||||
ScanKeyData entry[1]; /* VARIABLE LENGTH ARRAY */
|
|
||||||
} StrategyMapData; /* VARIABLE LENGTH STRUCTURE */
|
|
||||||
|
|
||||||
typedef StrategyMapData *StrategyMap;
|
|
||||||
|
|
||||||
typedef struct IndexStrategyData
|
|
||||||
{
|
|
||||||
StrategyMapData strategyMapData[1]; /* VARIABLE LENGTH ARRAY */
|
|
||||||
} IndexStrategyData; /* VARIABLE LENGTH STRUCTURE */
|
|
||||||
|
|
||||||
typedef IndexStrategyData *IndexStrategy;
|
|
||||||
|
|
||||||
#endif /* STRAT_H */
|
|
@ -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: valid.h,v 1.31 2003/09/25 18:58:35 tgl Exp $
|
* $Id: valid.h,v 1.32 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -31,15 +31,16 @@ do \
|
|||||||
/* We use underscores to protect the variable passed in as parameters */ \
|
/* We use underscores to protect the variable passed in as parameters */ \
|
||||||
/* We use two underscore here because this macro is included in the \
|
/* We use two underscore here because this macro is included in the \
|
||||||
macro below */ \
|
macro below */ \
|
||||||
bool __isnull; \
|
|
||||||
Datum __atp; \
|
|
||||||
Datum __test; \
|
|
||||||
int __cur_nkeys = (nkeys); \
|
int __cur_nkeys = (nkeys); \
|
||||||
ScanKey __cur_keys = (keys); \
|
ScanKey __cur_keys = (keys); \
|
||||||
\
|
\
|
||||||
(result) = true; /* may change */ \
|
(result) = true; /* may change */ \
|
||||||
for (; __cur_nkeys--; __cur_keys++) \
|
for (; __cur_nkeys--; __cur_keys++) \
|
||||||
{ \
|
{ \
|
||||||
|
Datum __atp; \
|
||||||
|
bool __isnull; \
|
||||||
|
Datum __test; \
|
||||||
|
\
|
||||||
__atp = heap_getattr((tuple), \
|
__atp = heap_getattr((tuple), \
|
||||||
__cur_keys->sk_attno, \
|
__cur_keys->sk_attno, \
|
||||||
(tupdesc), \
|
(tupdesc), \
|
||||||
@ -58,16 +59,11 @@ do \
|
|||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (__cur_keys->sk_flags & SK_COMMUTE) \
|
|
||||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
|
||||||
__cur_keys->sk_argument, __atp); \
|
|
||||||
else \
|
|
||||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
__test = FunctionCall2(&__cur_keys->sk_func, \
|
||||||
__atp, __cur_keys->sk_argument); \
|
__atp, __cur_keys->sk_argument); \
|
||||||
\
|
\
|
||||||
if (DatumGetBool(__test) == !!(__cur_keys->sk_flags & SK_NEGATE)) \
|
if (!DatumGetBool(__test)) \
|
||||||
{ \
|
{ \
|
||||||
/* XXX eventually should check if SK_ISNULL */ \
|
|
||||||
(result) = false; \
|
(result) = false; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
|
@ -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: sequence.h,v 1.26 2003/08/08 21:42:41 momjian Exp $
|
* $Id: sequence.h,v 1.27 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
|
#include "fmgr.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On a machine with no 64-bit-int C datatype, sizeof(int64) will not be 8,
|
* On a machine with no 64-bit-int C datatype, sizeof(int64) will not be 8,
|
||||||
|
@ -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.68 2003/08/08 21:42:48 momjian Exp $
|
* $Id: plannodes.h,v 1.69 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -153,15 +153,19 @@ typedef Scan SeqScan;
|
|||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* index scan node
|
* index scan node
|
||||||
|
*
|
||||||
|
* Note: this can actually represent N indexscans, all on the same table
|
||||||
|
* but potentially using different indexes, put together with OR semantics.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
typedef struct IndexScan
|
typedef struct IndexScan
|
||||||
{
|
{
|
||||||
Scan scan;
|
Scan scan;
|
||||||
List *indxid;
|
List *indxid; /* list of index OIDs (1 per scan) */
|
||||||
List *indxqual;
|
List *indxqual; /* list of sublists of index quals */
|
||||||
List *indxqualorig;
|
List *indxqualorig; /* the same in original form */
|
||||||
ScanDirection indxorderdir;
|
List *indxstrategy; /* list of sublists of strategy numbers */
|
||||||
|
ScanDirection indxorderdir; /* forward or backward or don't care */
|
||||||
} IndexScan;
|
} IndexScan;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* for developers. If you edit any of these, be sure to do a *full*
|
* for developers. If you edit any of these, be sure to do a *full*
|
||||||
* rebuild (and an initdb if noted).
|
* rebuild (and an initdb if noted).
|
||||||
*
|
*
|
||||||
* $Id: pg_config_manual.h,v 1.6 2003/09/21 17:57:21 tgl Exp $
|
* $Id: pg_config_manual.h,v 1.7 2003/11/09 21:30:37 tgl Exp $
|
||||||
*------------------------------------------------------------------------
|
*------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -229,7 +229,6 @@
|
|||||||
*/
|
*/
|
||||||
/* #define IPORTAL_DEBUG */
|
/* #define IPORTAL_DEBUG */
|
||||||
/* #define HEAPDEBUGALL */
|
/* #define HEAPDEBUGALL */
|
||||||
/* #define ISTRATDEBUG */
|
|
||||||
/* #define ACLDEBUG */
|
/* #define ACLDEBUG */
|
||||||
/* #define RTDEBUG */
|
/* #define RTDEBUG */
|
||||||
/* #define GISTDEBUG */
|
/* #define GISTDEBUG */
|
||||||
|
@ -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: smgr.h,v 1.37 2003/08/04 02:40:15 momjian Exp $
|
* $Id: smgr.h,v 1.38 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#define SMGR_H
|
#define SMGR_H
|
||||||
|
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
|
#include "fmgr.h"
|
||||||
#include "storage/relfilenode.h"
|
#include "storage/relfilenode.h"
|
||||||
#include "storage/block.h"
|
#include "storage/block.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
@ -13,7 +13,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: catcache.h,v 1.46 2003/08/04 02:40:15 momjian Exp $
|
* $Id: catcache.h,v 1.47 2003/11/09 21:30:37 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#define CATCACHE_H
|
#define CATCACHE_H
|
||||||
|
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
|
#include "access/skey.h"
|
||||||
#include "lib/dllist.h"
|
#include "lib/dllist.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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.82 2003/10/04 18:22:59 tgl Exp $
|
* $Id: lsyscache.h,v 1.83 2003/11/09 21:30:38 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -25,7 +25,8 @@ typedef enum IOFuncSelector
|
|||||||
} IOFuncSelector;
|
} IOFuncSelector;
|
||||||
|
|
||||||
extern bool op_in_opclass(Oid opno, Oid opclass);
|
extern bool op_in_opclass(Oid opno, Oid opclass);
|
||||||
extern bool op_requires_recheck(Oid opno, Oid opclass);
|
extern void get_op_opclass_properties(Oid opno, Oid opclass,
|
||||||
|
int *strategy, bool *recheck);
|
||||||
extern Oid get_opclass_member(Oid opclass, int16 strategy);
|
extern Oid get_opclass_member(Oid opclass, 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, int16 procnum);
|
||||||
|
@ -7,14 +7,13 @@
|
|||||||
* 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.68 2003/09/24 18:54:01 tgl Exp $
|
* $Id: rel.h,v 1.69 2003/11/09 21:30:38 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef REL_H
|
#ifndef REL_H
|
||||||
#define REL_H
|
#define REL_H
|
||||||
|
|
||||||
#include "access/strat.h"
|
|
||||||
#include "access/tupdesc.h"
|
#include "access/tupdesc.h"
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
@ -88,9 +87,8 @@ typedef struct TriggerDesc
|
|||||||
} TriggerDesc;
|
} TriggerDesc;
|
||||||
|
|
||||||
|
|
||||||
/* ----------
|
/*
|
||||||
* Same for the statistics collector data in Relation and scan data.
|
* Same for the statistics collector data in Relation and scan data.
|
||||||
* ----------
|
|
||||||
*/
|
*/
|
||||||
typedef struct PgStat_Info
|
typedef struct PgStat_Info
|
||||||
{
|
{
|
||||||
@ -138,9 +136,15 @@ typedef struct RelationData
|
|||||||
/* "struct HeapTupleData *" avoids need to include htup.h here */
|
/* "struct HeapTupleData *" avoids need to include htup.h here */
|
||||||
Form_pg_am rd_am; /* pg_am tuple for index's AM */
|
Form_pg_am rd_am; /* pg_am tuple for index's AM */
|
||||||
|
|
||||||
/* 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
|
||||||
|
* are cached, not any cross-type operators. The arrays are indexed by
|
||||||
|
* strategy or support number, which is a sufficient identifier given
|
||||||
|
* that restriction.
|
||||||
|
*/
|
||||||
MemoryContext rd_indexcxt; /* private memory cxt for this stuff */
|
MemoryContext rd_indexcxt; /* private memory cxt for this stuff */
|
||||||
IndexStrategy rd_istrat; /* operator strategy map */
|
|
||||||
Oid *rd_operator; /* OIDs of index operators */
|
Oid *rd_operator; /* OIDs of index operators */
|
||||||
RegProcedure *rd_support; /* OIDs of support procedures */
|
RegProcedure *rd_support; /* OIDs of support procedures */
|
||||||
struct FmgrInfo *rd_supportinfo; /* lookup info for support
|
struct FmgrInfo *rd_supportinfo; /* lookup info for support
|
||||||
@ -241,16 +245,6 @@ typedef Relation *RelationPtr;
|
|||||||
*/
|
*/
|
||||||
#define RelationGetDescr(relation) ((relation)->rd_att)
|
#define RelationGetDescr(relation) ((relation)->rd_att)
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationGetIndexStrategy
|
|
||||||
* Returns index strategy for a relation.
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Assumes relation descriptor is valid.
|
|
||||||
* Assumes relation descriptor is for an index relation.
|
|
||||||
*/
|
|
||||||
#define RelationGetIndexStrategy(relation) ((relation)->rd_istrat)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationGetRelationName
|
* RelationGetRelationName
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user