* tid.c
* Functions for the built-in type tuple id
*
- * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.50 2006/02/26 18:36:21 neilc Exp $
+ * src/backend/utils/adt/tid.c
*
* NOTES
* input routine largely stolen from boxin().
*/
#include "postgres.h"
-#include <errno.h>
#include <math.h>
#include <limits.h>
#include "access/heapam.h"
+#include "access/sysattr.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "libpq/pqformat.h"
+#include "miscadmin.h"
#include "parser/parsetree.h"
+#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/rel.h"
+#include "utils/snapmgr.h"
+#include "utils/tqual.h"
+#include "utils/varlena.h"
#define DatumGetItemPointer(X) ((ItemPointer) DatumGetPointer(X))
if (i < NTIDARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type tid: \"%s\"",
- str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "tid", str)));
errno = 0;
blockNumber = strtoul(coord[0], &badp, 10);
if (errno || *badp != DELIM)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type tid: \"%s\"",
- str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "tid", str)));
hold_offset = strtol(coord[1], &badp, 10);
if (errno || *badp != RDELIM ||
hold_offset > USHRT_MAX || hold_offset < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type tid: \"%s\"",
- str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "tid", str)));
offsetNumber = hold_offset;
tidout(PG_FUNCTION_ARGS)
{
ItemPointer itemPtr = PG_GETARG_ITEMPOINTER(0);
- BlockId blockId;
BlockNumber blockNumber;
OffsetNumber offsetNumber;
char buf[32];
- if (!ItemPointerIsValid(itemPtr))
- PG_RETURN_CSTRING(pstrdup("()"));
-
- blockId = &(itemPtr->ip_blkid);
- blockNumber = BlockIdGetBlockNumber(blockId);
+ blockNumber = BlockIdGetBlockNumber(&(itemPtr->ip_blkid));
offsetNumber = itemPtr->ip_posid;
+ /* Perhaps someday we should output this as a record. */
snprintf(buf, sizeof(buf), "(%u,%u)", blockNumber, offsetNumber);
PG_RETURN_CSTRING(pstrdup(buf));
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);
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) == 0);
}
Datum
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);
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) != 0);
+}
+
+Datum
+tidlt(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) < 0);
+}
+
+Datum
+tidle(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) <= 0);
}
+Datum
+tidgt(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) > 0);
+}
+
+Datum
+tidge(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_BOOL(ItemPointerCompare(arg1, arg2) >= 0);
+}
+
+Datum
+bttidcmp(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_INT32(ItemPointerCompare(arg1, arg2));
+}
+
+Datum
+tidlarger(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_ITEMPOINTER(ItemPointerCompare(arg1, arg2) >= 0 ? arg1 : arg2);
+}
+
+Datum
+tidsmaller(PG_FUNCTION_ARGS)
+{
+ ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
+ ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
+
+ PG_RETURN_ITEMPOINTER(ItemPointerCompare(arg1, arg2) <= 0 ? arg1 : arg2);
+}
+
+
/*
* Functions to get latest tid of a specified tuple.
*
Var *var = (Var *) tle->expr;
RangeTblEntry *rte;
- if (var->varno > 0 && var->varno < INNER &&
+ if (!IS_SPECIAL_VARNO(var->varno) &&
var->varattno == SelfItemPointerAttributeNumber)
{
rte = rt_fetch(var->varno, query->rtable);
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
ItemPointer result;
Relation rel;
+ AclResult aclresult;
+ Snapshot snapshot;
result = (ItemPointer) palloc(sizeof(ItemPointerData));
if (!reloid)
}
rel = heap_open(reloid, AccessShareLock);
+
+ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
+ ACL_SELECT);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_CLASS,
+ RelationGetRelationName(rel));
+
if (rel->rd_rel->relkind == RELKIND_VIEW)
return currtid_for_view(rel, tid);
ItemPointerCopy(tid, result);
- heap_get_latest_tid(rel, SnapshotNow, result);
+
+ snapshot = RegisterSnapshot(GetLatestSnapshot());
+ heap_get_latest_tid(rel, snapshot, result);
+ UnregisterSnapshot(snapshot);
heap_close(rel, AccessShareLock);
Datum
currtid_byrelname(PG_FUNCTION_ARGS)
{
- text *relname = PG_GETARG_TEXT_P(0);
+ text *relname = PG_GETARG_TEXT_PP(0);
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
ItemPointer result;
RangeVar *relrv;
Relation rel;
+ AclResult aclresult;
+ Snapshot snapshot;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = heap_openrv(relrv, AccessShareLock);
+
+ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
+ ACL_SELECT);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_CLASS,
+ RelationGetRelationName(rel));
+
if (rel->rd_rel->relkind == RELKIND_VIEW)
return currtid_for_view(rel, tid);
result = (ItemPointer) palloc(sizeof(ItemPointerData));
ItemPointerCopy(tid, result);
- heap_get_latest_tid(rel, SnapshotNow, result);
+ snapshot = RegisterSnapshot(GetLatestSnapshot());
+ heap_get_latest_tid(rel, snapshot, result);
+ UnregisterSnapshot(snapshot);
heap_close(rel, AccessShareLock);