mirror of
https://github.com/postgres/postgres.git
synced 2025-05-19 00:04:06 -04:00
per previous discussion on pghackers. Most of the duplicate code in different AMs' ambuild routines has been moved out to a common routine in index.c; this means that all index types now do the right things about inserting recently-dead tuples, etc. (I also removed support for EXTEND INDEX in the ambuild routines, since that's about to go away anyway, and it cluttered the code a lot.) The retail indextuple deletion routines have been replaced by a "bulk delete" routine in which the indexscan is inside the access method. I haven't pushed this change as far as it should go yet, but it should allow considerable simplification of the internal bookkeeping for deletions. Also, add flag columns to pg_am to eliminate various hardcoded tests on AM OIDs, and remove unused pg_am columns. Fix rtree and gist index types to not attempt to store NULLs; before this, gist usually crashed, while rtree managed not to crash but computed wacko bounding boxes for NULL entries (which might have had something to do with the performance problems we've heard about occasionally). Add AtEOXact routines to hash, rtree, and gist, all of which have static state that needs to be reset after an error. We discovered this need long ago for btree, but missed the other guys. Oh, one more thing: concurrent VACUUM is now the default.
139 lines
3.9 KiB
C
139 lines
3.9 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* rtree.h
|
|
* common declarations for the rtree access method code.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* $Id: rtree.h,v 1.24 2001/07/15 22:48:18 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef RTREE_H
|
|
#define RTREE_H
|
|
|
|
#include "access/itup.h"
|
|
#include "access/sdir.h"
|
|
#include "access/skey.h"
|
|
#include "access/xlog.h"
|
|
#include "utils/rel.h"
|
|
|
|
/* see rtstrat.c for what all this is about */
|
|
#define RTNStrategies 8
|
|
#define RTLeftStrategyNumber 1
|
|
#define RTOverLeftStrategyNumber 2
|
|
#define RTOverlapStrategyNumber 3
|
|
#define RTOverRightStrategyNumber 4
|
|
#define RTRightStrategyNumber 5
|
|
#define RTSameStrategyNumber 6
|
|
#define RTContainsStrategyNumber 7
|
|
#define RTContainedByStrategyNumber 8
|
|
|
|
#define RTNProcs 3
|
|
#define RT_UNION_PROC 1
|
|
#define RT_INTER_PROC 2
|
|
#define RT_SIZE_PROC 3
|
|
|
|
#define F_LEAF (1 << 0)
|
|
|
|
typedef struct RTreePageOpaqueData
|
|
{
|
|
uint32 flags;
|
|
} RTreePageOpaqueData;
|
|
|
|
typedef RTreePageOpaqueData *RTreePageOpaque;
|
|
|
|
/*
|
|
* When we descend a tree, we keep a stack of parent pointers.
|
|
*/
|
|
|
|
typedef struct RTSTACK
|
|
{
|
|
struct RTSTACK *rts_parent;
|
|
OffsetNumber rts_child;
|
|
BlockNumber rts_blk;
|
|
} RTSTACK;
|
|
|
|
/*
|
|
* When we're doing a scan, we need to keep track of the parent stack
|
|
* for the marked and current items. Also, rtrees have the following
|
|
* property: if you're looking for the box (1,1,2,2), on the internal
|
|
* nodes you have to search for all boxes that *contain* (1,1,2,2), and
|
|
* not the ones that match it. We have a private scan key for internal
|
|
* nodes in the opaque structure for rtrees for this reason. See
|
|
* access/index-rtree/rtscan.c and rtstrat.c for how it gets initialized.
|
|
*/
|
|
|
|
typedef struct RTreeScanOpaqueData
|
|
{
|
|
struct RTSTACK *s_stack;
|
|
struct RTSTACK *s_markstk;
|
|
uint16 s_flags;
|
|
uint16 s_internalNKey;
|
|
ScanKey s_internalKey;
|
|
} RTreeScanOpaqueData;
|
|
|
|
typedef RTreeScanOpaqueData *RTreeScanOpaque;
|
|
|
|
/*
|
|
* When we're doing a scan and updating a tree at the same time, the
|
|
* updates may affect the scan. We use the flags entry of the scan's
|
|
* opaque space to record our actual position in response to updates
|
|
* that we can't handle simply by adjusting pointers.
|
|
*/
|
|
|
|
#define RTS_CURBEFORE ((uint16) (1 << 0))
|
|
#define RTS_MRKBEFORE ((uint16) (1 << 1))
|
|
|
|
/* root page of an rtree */
|
|
#define P_ROOT 0
|
|
|
|
/*
|
|
* When we update a relation on which we're doing a scan, we need to
|
|
* check the scan and fix it if the update affected any of the pages it
|
|
* touches. Otherwise, we can miss records that we should see. The only
|
|
* times we need to do this are for deletions and splits. See the code in
|
|
* rtscan.c for how the scan is fixed. These two contants tell us what sort
|
|
* of operation changed the index.
|
|
*/
|
|
|
|
#define RTOP_DEL 0
|
|
#define RTOP_SPLIT 1
|
|
|
|
/* defined in rtree.c */
|
|
extern void freestack(RTSTACK *s);
|
|
|
|
/*
|
|
* RTree code.
|
|
* Defined in access/rtree/
|
|
*/
|
|
extern Datum rtinsert(PG_FUNCTION_ARGS);
|
|
extern Datum rtbulkdelete(PG_FUNCTION_ARGS);
|
|
|
|
extern Datum rtgettuple(PG_FUNCTION_ARGS);
|
|
extern Datum rtbeginscan(PG_FUNCTION_ARGS);
|
|
|
|
extern Datum rtendscan(PG_FUNCTION_ARGS);
|
|
extern Datum rtmarkpos(PG_FUNCTION_ARGS);
|
|
extern Datum rtrestrpos(PG_FUNCTION_ARGS);
|
|
extern Datum rtrescan(PG_FUNCTION_ARGS);
|
|
extern Datum rtbuild(PG_FUNCTION_ARGS);
|
|
extern void _rtdump(Relation r);
|
|
|
|
extern void rtree_redo(XLogRecPtr lsn, XLogRecord *record);
|
|
extern void rtree_undo(XLogRecPtr lsn, XLogRecord *record);
|
|
extern void rtree_desc(char *buf, uint8 xl_info, char *rec);
|
|
|
|
/* rtscan.c */
|
|
extern void rtadjscans(Relation r, int op, BlockNumber blkno,
|
|
OffsetNumber offnum);
|
|
extern void AtEOXact_rtree(void);
|
|
|
|
/* rtstrat.c */
|
|
extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
|
|
RegProcedure proc);
|
|
|
|
#endif /* RTREE_H */
|