postgresql/src/backend/utils/adt/tid.c

180 lines
4.4 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* tid.c
* Functions for the built-in type tuple id
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
2001-03-22 05:01:46 +01:00
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.24 2001/03/22 03:59:54 momjian Exp $
*
* NOTES
* input routine largely stolen from boxin().
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
1999-07-16 05:14:30 +02:00
#include "utils/builtins.h"
2001-03-22 05:01:46 +01:00
#define DatumGetItemPointer(X) ((ItemPointer) DatumGetPointer(X))
#define ItemPointerGetDatum(X) PointerGetDatum(X)
#define PG_GETARG_ITEMPOINTER(n) DatumGetItemPointer(PG_GETARG_DATUM(n))
#define PG_RETURN_ITEMPOINTER(x) return ItemPointerGetDatum(x)
#define LDELIM '('
#define RDELIM ')'
#define DELIM ','
#define NTIDARGS 2
/* ----------------------------------------------------------------
* tidin
* ----------------------------------------------------------------
*/
Datum
tidin(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
char *p,
*coord[NTIDARGS];
int i;
ItemPointer result;
BlockNumber blockNumber;
OffsetNumber offsetNumber;
for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
if (*p == DELIM || (*p == LDELIM && !i))
coord[i++] = p + 1;
if (i < NTIDARGS)
elog(ERROR, "invalid tid format: '%s'", str);
blockNumber = (BlockNumber) atoi(coord[0]);
offsetNumber = (OffsetNumber) atoi(coord[1]);
result = (ItemPointer) palloc(sizeof(ItemPointerData));
ItemPointerSet(result, blockNumber, offsetNumber);
PG_RETURN_ITEMPOINTER(result);
}
/* ----------------------------------------------------------------
* tidout
* ----------------------------------------------------------------
*/
Datum
tidout(PG_FUNCTION_ARGS)
{
2001-03-22 05:01:46 +01:00
ItemPointer itemPtr = PG_GETARG_ITEMPOINTER(0);
BlockId blockId;
BlockNumber blockNumber;
OffsetNumber offsetNumber;
char buf[32];
static char *invalidTid = "()";
if (!ItemPointerIsValid(itemPtr))
PG_RETURN_CSTRING(pstrdup(invalidTid));
blockId = &(itemPtr->ip_blkid);
blockNumber = BlockIdGetBlockNumber(blockId);
offsetNumber = itemPtr->ip_posid;
sprintf(buf, "(%d,%d)", (int) blockNumber, (int) offsetNumber);
PG_RETURN_CSTRING(pstrdup(buf));
}
/*****************************************************************************
* PUBLIC ROUTINES *
*****************************************************************************/
Datum
tideq(PG_FUNCTION_ARGS)
{
2001-03-22 05:01:46 +01:00
ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
PG_RETURN_BOOL(BlockIdGetBlockNumber(&(arg1->ip_blkid)) ==
BlockIdGetBlockNumber(&(arg2->ip_blkid)) &&
arg1->ip_posid == arg2->ip_posid);
}
#ifdef NOT_USED
Datum
tidne(PG_FUNCTION_ARGS)
{
2001-03-22 05:01:46 +01:00
ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
PG_RETURN_BOOL(BlockIdGetBlockNumber(&(arg1->ip_blkid)) !=
BlockIdGetBlockNumber(&(arg2->ip_blkid)) ||
arg1->ip_posid != arg2->ip_posid);
}
2001-03-22 05:01:46 +01:00
#endif
/*
* Functions to get latest tid of a specified tuple.
*
* Maybe these implementations should be moved to another place
*/
Datum
currtid_byreloid(PG_FUNCTION_ARGS)
{
2001-03-22 05:01:46 +01:00
Oid reloid = PG_GETARG_OID(0);
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
ItemPointer result,
ret;
Relation rel;
result = (ItemPointer) palloc(sizeof(ItemPointerData));
ItemPointerSetInvalid(result);
if ((rel = heap_open(reloid, AccessShareLock)) != NULL)
{
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);
PG_RETURN_ITEMPOINTER(result);
}
Datum
currtid_byrelname(PG_FUNCTION_ARGS)
{
2001-03-22 05:01:46 +01:00
text *relname = PG_GETARG_TEXT_P(0);
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
ItemPointer result,
ret;
char *str;
Relation rel;
str = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(relname)));
result = (ItemPointer) palloc(sizeof(ItemPointerData));
ItemPointerSetInvalid(result);
if ((rel = heap_openr(str, AccessShareLock)) != NULL)
{
ret = heap_get_latest_tid(rel, SnapshotNow, tid);
if (ret)
ItemPointerCopy(ret, result);
heap_close(rel, AccessShareLock);
}
else
elog(ERROR, "Relation %s not found", str);
pfree(str);
PG_RETURN_ITEMPOINTER(result);
}