mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-28 00:41:52 +02:00
The 1st step to implement new type of scan,TidScan.
Now WHERE restriction on ctid is allowed though it is sequentially scanned.
This commit is contained in:
parent
65a2c8f5b8
commit
05d13cad28
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.55 1999/09/24 00:23:54 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.56 1999/10/11 06:28:27 inoue Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -1086,6 +1086,95 @@ heap_fetch(Relation relation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* heap_get_latest_tid - get the latest tid of a specified tuple
|
||||||
|
*
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
ItemPointer
|
||||||
|
heap_get_latest_tid(Relation relation,
|
||||||
|
Snapshot snapshot,
|
||||||
|
ItemPointer tid)
|
||||||
|
{
|
||||||
|
ItemId lp;
|
||||||
|
Buffer buffer;
|
||||||
|
PageHeader dp;
|
||||||
|
OffsetNumber offnum;
|
||||||
|
HeapTupleData tp;
|
||||||
|
HeapTupleHeader t_data;
|
||||||
|
ItemPointerData ctid;
|
||||||
|
bool invalidBlock,linkend;
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* get the buffer from the relation descriptor
|
||||||
|
* Note that this does a buffer pin.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
|
||||||
|
|
||||||
|
if (!BufferIsValid(buffer))
|
||||||
|
elog(ERROR, "heap_get_latest_tid: %s relation: ReadBuffer(%lx) failed",
|
||||||
|
&relation->rd_rel->relname, (long) tid);
|
||||||
|
|
||||||
|
LockBuffer(buffer, BUFFER_LOCK_SHARE);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* get the item line pointer corresponding to the requested tid
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
dp = (PageHeader) BufferGetPage(buffer);
|
||||||
|
offnum = ItemPointerGetOffsetNumber(tid);
|
||||||
|
invalidBlock = true;
|
||||||
|
if (!PageIsNew(dp))
|
||||||
|
{
|
||||||
|
lp = PageGetItemId(dp, offnum);
|
||||||
|
if (ItemIdIsUsed(lp))
|
||||||
|
invalidBlock = false;
|
||||||
|
}
|
||||||
|
if (invalidBlock)
|
||||||
|
{
|
||||||
|
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||||
|
ReleaseBuffer(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* more sanity checks
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
t_data = tp.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
|
||||||
|
tp.t_len = ItemIdGetLength(lp);
|
||||||
|
tp.t_self = *tid;
|
||||||
|
ctid = tp.t_data->t_ctid;
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* check time qualification of tid
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
HeapTupleSatisfies(&tp, relation, buffer, dp,
|
||||||
|
snapshot, 0, (ScanKey) NULL);
|
||||||
|
|
||||||
|
linkend = true;
|
||||||
|
if ((t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
|
||||||
|
!ItemPointerEquals(tid, &ctid))
|
||||||
|
linkend = false;
|
||||||
|
|
||||||
|
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||||
|
ReleaseBuffer(buffer);
|
||||||
|
|
||||||
|
if (tp.t_data == NULL)
|
||||||
|
{
|
||||||
|
if (linkend)
|
||||||
|
return NULL;
|
||||||
|
return heap_get_latest_tid(relation, snapshot, &ctid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tid;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* heap_insert - insert tuple
|
* heap_insert - insert tuple
|
||||||
*
|
*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.11 1999/07/17 20:18:00 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.12 1999/10/11 06:28:26 inoue Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* input routine largely stolen from boxin().
|
* input routine largely stolen from boxin().
|
||||||
@ -28,9 +28,9 @@
|
|||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
ItemPointer
|
ItemPointer
|
||||||
tidin(char *str)
|
tidin(const char *str)
|
||||||
{
|
{
|
||||||
char *p,
|
const char *p,
|
||||||
*coord[NTIDARGS];
|
*coord[NTIDARGS];
|
||||||
int i;
|
int i;
|
||||||
ItemPointer result;
|
ItemPointer result;
|
||||||
@ -45,8 +45,12 @@ tidin(char *str)
|
|||||||
if (*p == DELIM || (*p == LDELIM && !i))
|
if (*p == DELIM || (*p == LDELIM && !i))
|
||||||
coord[i++] = p + 1;
|
coord[i++] = p + 1;
|
||||||
|
|
||||||
if (i < NTIDARGS - 1)
|
/* if (i < NTIDARGS - 1) */
|
||||||
|
if (i < NTIDARGS)
|
||||||
|
{
|
||||||
|
elog(ERROR, "%s invalid tid format", str);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
blockNumber = (BlockNumber) atoi(coord[0]);
|
blockNumber = (BlockNumber) atoi(coord[0]);
|
||||||
offsetNumber = (OffsetNumber) atoi(coord[1]);
|
offsetNumber = (OffsetNumber) atoi(coord[1]);
|
||||||
@ -70,6 +74,14 @@ tidout(ItemPointer itemPtr)
|
|||||||
BlockId blockId;
|
BlockId blockId;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
char *str;
|
char *str;
|
||||||
|
static char *invalidTid = "()";
|
||||||
|
|
||||||
|
if (!itemPtr || !ItemPointerIsValid(itemPtr))
|
||||||
|
{
|
||||||
|
str = palloc(strlen(invalidTid));
|
||||||
|
strcpy(str, invalidTid);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
blockId = &(itemPtr->ip_blkid);
|
blockId = &(itemPtr->ip_blkid);
|
||||||
|
|
||||||
@ -83,3 +95,113 @@ tidout(ItemPointer itemPtr)
|
|||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* PUBLIC ROUTINES *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
bool
|
||||||
|
tideq(ItemPointer arg1, ItemPointer arg2)
|
||||||
|
{
|
||||||
|
if ((!arg1) || (!arg2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( BlockIdGetBlockNumber(&(arg1->ip_blkid)) ==
|
||||||
|
BlockIdGetBlockNumber(&(arg2->ip_blkid)) &&
|
||||||
|
arg1->ip_posid == arg2->ip_posid );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
tidne(ItemPointer arg1, ItemPointer arg2)
|
||||||
|
{
|
||||||
|
if ((!arg1) || (!arg2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ( BlockIdGetBlockNumber(&(arg1->ip_blkid)) !=
|
||||||
|
BlockIdGetBlockNumber(&(arg2->ip_blkid)) ||
|
||||||
|
arg1->ip_posid != arg2->ip_posid );
|
||||||
|
}
|
||||||
|
|
||||||
|
text *
|
||||||
|
tid_text(ItemPointer tid)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (!tid) return (text *)NULL;
|
||||||
|
str = tidout(tid);
|
||||||
|
|
||||||
|
return textin(str);
|
||||||
|
} /* tid_text() */
|
||||||
|
|
||||||
|
ItemPointer
|
||||||
|
text_tid(const text *string)
|
||||||
|
{
|
||||||
|
ItemPointer result;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (!string) return (ItemPointer)0;
|
||||||
|
|
||||||
|
str = textout(string);
|
||||||
|
result = tidin(str);
|
||||||
|
pfree(str);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} /* text_tid() */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions to get latest tid of a specified tuple.
|
||||||
|
* Maybe these implementations is moved
|
||||||
|
* to another place
|
||||||
|
*/
|
||||||
|
#include <utils/relcache.h>
|
||||||
|
ItemPointer
|
||||||
|
currtid_byreloid(Oid reloid, ItemPointer tid)
|
||||||
|
{
|
||||||
|
ItemPointer result = NULL, ret;
|
||||||
|
Relation rel;
|
||||||
|
|
||||||
|
result = (ItemPointer) palloc(sizeof(ItemPointerData));
|
||||||
|
ItemPointerSetInvalid(result);
|
||||||
|
if (rel = heap_open(reloid, AccessShareLock), rel)
|
||||||
|
{
|
||||||
|
ret = heap_get_latest_tid(rel, SnapshotNow, tid);
|
||||||
|
if (ret)
|
||||||
|
ItemPointerCopy(ret, result);
|
||||||
|
heap_close(rel, AccessShareLock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
elog(ERROR, "Relation %u not found", reloid);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} /* currtid_byreloid() */
|
||||||
|
|
||||||
|
ItemPointer
|
||||||
|
currtid_byrelname(const text *relname, ItemPointer tid)
|
||||||
|
{
|
||||||
|
ItemPointer result = NULL, ret;
|
||||||
|
char *str;
|
||||||
|
Relation rel;
|
||||||
|
|
||||||
|
if (!relname) return result;
|
||||||
|
|
||||||
|
str = textout(relname);
|
||||||
|
|
||||||
|
result = (ItemPointer) palloc(sizeof(ItemPointerData));
|
||||||
|
ItemPointerSetInvalid(result);
|
||||||
|
if (rel = heap_openr(str, AccessShareLock), rel)
|
||||||
|
{
|
||||||
|
ret = heap_get_latest_tid(rel, SnapshotNow, tid);
|
||||||
|
if (ret)
|
||||||
|
ItemPointerCopy(ret, result);
|
||||||
|
heap_close(rel, AccessShareLock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
elog(ERROR, "Relation %s not found", relname);
|
||||||
|
pfree(str);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} /* currtid_byrelname() */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: heapam.h,v 1.46 1999/09/18 19:08:13 tgl Exp $
|
* $Id: heapam.h,v 1.47 1999/10/11 06:28:29 inoue Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -256,6 +256,7 @@ extern void heap_rescan(HeapScanDesc scan, bool scanFromEnd, ScanKey key);
|
|||||||
extern void heap_endscan(HeapScanDesc scan);
|
extern void heap_endscan(HeapScanDesc scan);
|
||||||
extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw);
|
extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw);
|
||||||
extern void heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tup, Buffer *userbuf);
|
extern void heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tup, Buffer *userbuf);
|
||||||
|
extern ItemPointer heap_get_latest_tid(Relation relation, Snapshot snapshot, ItemPointer tid);
|
||||||
extern Oid heap_insert(Relation relation, HeapTuple tup);
|
extern Oid heap_insert(Relation relation, HeapTuple tup);
|
||||||
extern int heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid);
|
extern int heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid);
|
||||||
extern int heap_replace(Relation relation, ItemPointer otid, HeapTuple tup,
|
extern int heap_replace(Relation relation, ItemPointer otid, HeapTuple tup,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_operator.h,v 1.59 1999/09/06 21:16:18 tgl Exp $
|
* $Id: pg_operator.h,v 1.60 1999/10/11 06:28:29 inoue Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -136,6 +136,9 @@ DATA(insert OID = 399 ( "=" PGUID 0 b t f 1026 1026 16 399 0 0 0 array_e
|
|||||||
DATA(insert OID = 400 ( "=" PGUID 0 b t f 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
|
DATA(insert OID = 400 ( "=" PGUID 0 b t f 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
|
||||||
DATA(insert OID = 401 ( "=" PGUID 0 b t f 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
|
DATA(insert OID = 401 ( "=" PGUID 0 b t f 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
|
||||||
|
|
||||||
|
DATA(insert OID = 387 ( "=" PGUID 0 b t t 27 27 16 387 0 0 0 tideq eqsel eqjoinsel ));
|
||||||
|
#define TIDEqualOperator 387
|
||||||
|
|
||||||
DATA(insert OID = 410 ( "=" PGUID 0 b t t 20 20 16 410 411 412 412 int8eq eqsel eqjoinsel ));
|
DATA(insert OID = 410 ( "=" PGUID 0 b t t 20 20 16 410 411 412 412 int8eq eqsel eqjoinsel ));
|
||||||
DATA(insert OID = 411 ( "<>" PGUID 0 b t f 20 20 16 411 410 0 0 int8ne neqsel neqjoinsel ));
|
DATA(insert OID = 411 ( "<>" PGUID 0 b t f 20 20 16 411 410 0 0 int8ne neqsel neqjoinsel ));
|
||||||
DATA(insert OID = 412 ( "<" PGUID 0 b t f 20 20 16 413 415 0 0 int8lt intltsel intltjoinsel ));
|
DATA(insert OID = 412 ( "<" PGUID 0 b t f 20 20 16 413 415 0 0 int8lt intltsel intltjoinsel ));
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_proc.h,v 1.104 1999/09/30 14:54:23 wieck Exp $
|
* $Id: pg_proc.h,v 1.105 1999/10/11 06:28:28 inoue Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -1560,6 +1560,13 @@ DESCR("truncate _char()");
|
|||||||
DATA(insert OID = 1291 ( _varchar PGUID 11 f t t 2 f 1015 "1015 23" 100 0 0 100 _varchar - ));
|
DATA(insert OID = 1291 ( _varchar PGUID 11 f t t 2 f 1015 "1015 23" 100 0 0 100 _varchar - ));
|
||||||
DESCR("truncate _varchar()");
|
DESCR("truncate _varchar()");
|
||||||
|
|
||||||
|
DATA(insert OID = 1292 ( tideq PGUID 11 f t f 2 f 16 "27 27" 100 0 0 100 tideq - ));
|
||||||
|
DESCR("equal");
|
||||||
|
DATA(insert OID = 1293 ( currtid PGUID 11 f t f 2 f 27 "26 27" 100 0 0 100 currtid_byreloid - ));
|
||||||
|
DESCR("latest tid of a tuple");
|
||||||
|
DATA(insert OID = 1294 ( currtid2 PGUID 11 f t f 2 f 27 "25 27" 100 0 0 100 currtid_byrelname - ));
|
||||||
|
DESCR("latest tid of a tuple");
|
||||||
|
|
||||||
DATA(insert OID = 1297 ( timestamp_in PGUID 11 f t f 1 f 1296 "0" 100 0 0 100 timestamp_in - ));
|
DATA(insert OID = 1297 ( timestamp_in PGUID 11 f t f 1 f 1296 "0" 100 0 0 100 timestamp_in - ));
|
||||||
DESCR("(internal)");
|
DESCR("(internal)");
|
||||||
DATA(insert OID = 1298 ( timestamp_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 timestamp_out - ));
|
DATA(insert OID = 1298 ( timestamp_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 timestamp_out - ));
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: builtins.h,v 1.88 1999/10/03 23:55:37 tgl Exp $
|
* $Id: builtins.h,v 1.89 1999/10/11 06:28:28 inoue Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* This should normally only be included by fmgr.h.
|
* This should normally only be included by fmgr.h.
|
||||||
@ -399,8 +399,14 @@ extern float64 gistsel(Oid operatorObjectId, Oid indrelid, AttrNumber attributeN
|
|||||||
extern float64 gistnpage(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
|
extern float64 gistnpage(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
|
||||||
|
|
||||||
/* tid.c */
|
/* tid.c */
|
||||||
extern ItemPointer tidin(char *str);
|
extern ItemPointer tidin(const char *str);
|
||||||
extern char *tidout(ItemPointer itemPtr);
|
extern char *tidout(ItemPointer itemPtr);
|
||||||
|
extern bool tideq(ItemPointer,ItemPointer);
|
||||||
|
extern bool tidne(ItemPointer,ItemPointer);
|
||||||
|
extern text *tid_text(ItemPointer);
|
||||||
|
extern ItemPointer text_tid(const text *);
|
||||||
|
extern ItemPointer currtid_byreloid(Oid relOid, ItemPointer);
|
||||||
|
extern ItemPointer currtid_byrelname(const text* relName, ItemPointer);
|
||||||
|
|
||||||
/* timestamp.c */
|
/* timestamp.c */
|
||||||
extern time_t timestamp_in(const char *timestamp_str);
|
extern time_t timestamp_in(const char *timestamp_str);
|
||||||
|
Loading…
Reference in New Issue
Block a user