1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* tid.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* Functions for the built-in type tuple id
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2000-01-26 06:58:53 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.15 2000/01/26 05:57:14 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* NOTES
|
1997-09-07 07:04:48 +02:00
|
|
|
* input routine largely stolen from boxin().
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
1999-07-17 22:18:55 +02:00
|
|
|
#include "postgres.h"
|
1999-07-16 05:14:30 +02:00
|
|
|
#include "utils/builtins.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
#define LDELIM '('
|
|
|
|
#define RDELIM ')'
|
|
|
|
#define DELIM ','
|
|
|
|
#define NTIDARGS 2
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* tidin
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
ItemPointer
|
1999-10-11 08:28:29 +02:00
|
|
|
tidin(const char *str)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1999-10-11 08:28:29 +02:00
|
|
|
const char *p,
|
1997-09-08 04:41:22 +02:00
|
|
|
*coord[NTIDARGS];
|
|
|
|
int i;
|
|
|
|
ItemPointer result;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
BlockNumber blockNumber;
|
|
|
|
OffsetNumber offsetNumber;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (str == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
|
|
|
|
if (*p == DELIM || (*p == LDELIM && !i))
|
|
|
|
coord[i++] = p + 1;
|
|
|
|
|
1999-10-11 08:28:29 +02:00
|
|
|
/* if (i < NTIDARGS - 1) */
|
|
|
|
if (i < NTIDARGS)
|
|
|
|
{
|
|
|
|
elog(ERROR, "%s invalid tid format", str);
|
1997-09-07 07:04:48 +02:00
|
|
|
return NULL;
|
1999-10-11 08:28:29 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
blockNumber = (BlockNumber) atoi(coord[0]);
|
|
|
|
offsetNumber = (OffsetNumber) atoi(coord[1]);
|
|
|
|
|
|
|
|
result = (ItemPointer) palloc(sizeof(ItemPointerData));
|
|
|
|
|
|
|
|
ItemPointerSet(result, blockNumber, offsetNumber);
|
|
|
|
|
|
|
|
return result;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* tidout
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
char *
|
1996-07-09 08:22:35 +02:00
|
|
|
tidout(ItemPointer itemPtr)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
BlockNumber blockNumber;
|
|
|
|
OffsetNumber offsetNumber;
|
|
|
|
BlockId blockId;
|
|
|
|
char buf[32];
|
|
|
|
char *str;
|
1999-10-11 08:28:29 +02:00
|
|
|
static char *invalidTid = "()";
|
|
|
|
|
|
|
|
if (!itemPtr || !ItemPointerIsValid(itemPtr))
|
|
|
|
{
|
|
|
|
str = palloc(strlen(invalidTid));
|
|
|
|
strcpy(str, invalidTid);
|
|
|
|
return str;
|
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
blockId = &(itemPtr->ip_blkid);
|
|
|
|
|
|
|
|
blockNumber = BlockIdGetBlockNumber(blockId);
|
|
|
|
offsetNumber = itemPtr->ip_posid;
|
|
|
|
|
|
|
|
sprintf(buf, "(%d,%d)", blockNumber, offsetNumber);
|
|
|
|
|
|
|
|
str = (char *) palloc(strlen(buf) + 1);
|
|
|
|
strcpy(str, buf);
|
|
|
|
|
|
|
|
return str;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1999-10-11 08:28:29 +02:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* 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;
|
|
|
|
|
1999-12-20 02:23:04 +01:00
|
|
|
str = textout((text *) string);
|
1999-10-11 08:28:29 +02:00
|
|
|
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;
|
|
|
|
|
1999-12-20 02:23:04 +01:00
|
|
|
str = textout((text *) relname);
|
1999-10-11 08:28:29 +02:00
|
|
|
|
|
|
|
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
|
2000-01-15 03:59:43 +01:00
|
|
|
elog(ERROR, "Relation %s not found", textout((text *)relname));
|
1999-10-11 08:28:29 +02:00
|
|
|
pfree(str);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
} /* currtid_byrelname() */
|