]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/tid.c
Further cleanups for relations in schemas: teach nextval and other
[postgresql] / src / backend / utils / adt / tid.c
1 /*-------------------------------------------------------------------------
2  *
3  * tid.c
4  *        Functions for the built-in type tuple id
5  *
6  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.29 2002/03/30 01:02:41 tgl Exp $
12  *
13  * NOTES
14  *        input routine largely stolen from boxin().
15  *
16  *-------------------------------------------------------------------------
17  */
18
19 #include "postgres.h"
20
21 #include "access/heapam.h"
22 #include "catalog/namespace.h"
23 #include "utils/builtins.h"
24
25 #define DatumGetItemPointer(X)   ((ItemPointer) DatumGetPointer(X))
26 #define ItemPointerGetDatum(X)   PointerGetDatum(X)
27 #define PG_GETARG_ITEMPOINTER(n) DatumGetItemPointer(PG_GETARG_DATUM(n))
28 #define PG_RETURN_ITEMPOINTER(x) return ItemPointerGetDatum(x)
29
30 #define LDELIM                  '('
31 #define RDELIM                  ')'
32 #define DELIM                   ','
33 #define NTIDARGS                2
34
35 /* ----------------------------------------------------------------
36  *              tidin
37  * ----------------------------------------------------------------
38  */
39 Datum
40 tidin(PG_FUNCTION_ARGS)
41 {
42         char       *str = PG_GETARG_CSTRING(0);
43         char       *p,
44                            *coord[NTIDARGS];
45         int                     i;
46         ItemPointer result;
47         BlockNumber blockNumber;
48         OffsetNumber offsetNumber;
49
50         for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
51                 if (*p == DELIM || (*p == LDELIM && !i))
52                         coord[i++] = p + 1;
53
54         if (i < NTIDARGS)
55                 elog(ERROR, "invalid tid format: '%s'", str);
56
57         blockNumber = (BlockNumber) atoi(coord[0]);
58         offsetNumber = (OffsetNumber) atoi(coord[1]);
59
60         result = (ItemPointer) palloc(sizeof(ItemPointerData));
61
62         ItemPointerSet(result, blockNumber, offsetNumber);
63
64         PG_RETURN_ITEMPOINTER(result);
65 }
66
67 /* ----------------------------------------------------------------
68  *              tidout
69  * ----------------------------------------------------------------
70  */
71 Datum
72 tidout(PG_FUNCTION_ARGS)
73 {
74         ItemPointer itemPtr = PG_GETARG_ITEMPOINTER(0);
75         BlockId         blockId;
76         BlockNumber blockNumber;
77         OffsetNumber offsetNumber;
78         char            buf[32];
79         static char *invalidTid = "()";
80
81         if (!ItemPointerIsValid(itemPtr))
82                 PG_RETURN_CSTRING(pstrdup(invalidTid));
83
84         blockId = &(itemPtr->ip_blkid);
85
86         blockNumber = BlockIdGetBlockNumber(blockId);
87         offsetNumber = itemPtr->ip_posid;
88
89         sprintf(buf, "(%d,%d)", (int) blockNumber, (int) offsetNumber);
90
91         PG_RETURN_CSTRING(pstrdup(buf));
92 }
93
94 /*****************************************************************************
95  *       PUBLIC ROUTINES                                                                                                                 *
96  *****************************************************************************/
97
98 Datum
99 tideq(PG_FUNCTION_ARGS)
100 {
101         ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
102         ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
103
104         PG_RETURN_BOOL(BlockIdGetBlockNumber(&(arg1->ip_blkid)) ==
105                                    BlockIdGetBlockNumber(&(arg2->ip_blkid)) &&
106                                    arg1->ip_posid == arg2->ip_posid);
107 }
108
109 #ifdef NOT_USED
110 Datum
111 tidne(PG_FUNCTION_ARGS)
112 {
113         ItemPointer arg1 = PG_GETARG_ITEMPOINTER(0);
114         ItemPointer arg2 = PG_GETARG_ITEMPOINTER(1);
115
116         PG_RETURN_BOOL(BlockIdGetBlockNumber(&(arg1->ip_blkid)) !=
117                                    BlockIdGetBlockNumber(&(arg2->ip_blkid)) ||
118                                    arg1->ip_posid != arg2->ip_posid);
119 }
120 #endif
121
122 /*
123  *      Functions to get latest tid of a specified tuple.
124  *
125  *      Maybe these implementations should be moved to another place
126  */
127
128 static ItemPointerData Current_last_tid = {{0, 0}, 0};
129
130 void
131 setLastTid(const ItemPointer tid)
132 {
133         Current_last_tid = *tid;
134 }
135
136 Datum
137 currtid_byreloid(PG_FUNCTION_ARGS)
138 {
139         Oid                     reloid = PG_GETARG_OID(0);
140         ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
141         ItemPointer result;
142         Relation        rel;
143
144         result = (ItemPointer) palloc(sizeof(ItemPointerData));
145         if (!reloid)
146         {
147                 *result = Current_last_tid;
148                 PG_RETURN_ITEMPOINTER(result);
149         }
150
151         rel = heap_open(reloid, AccessShareLock);
152
153         ItemPointerCopy(tid, result);
154         heap_get_latest_tid(rel, SnapshotNow, result);
155
156         heap_close(rel, AccessShareLock);
157
158         PG_RETURN_ITEMPOINTER(result);
159 }
160
161 Datum
162 currtid_byrelname(PG_FUNCTION_ARGS)
163 {
164         text       *relname = PG_GETARG_TEXT_P(0);
165         ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
166         ItemPointer result;
167         RangeVar   *relrv;
168         Relation        rel;
169
170         relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
171                                                                                                                 "currtid_byrelname"));
172         rel = heap_openrv(relrv, AccessShareLock);
173
174         result = (ItemPointer) palloc(sizeof(ItemPointerData));
175         ItemPointerCopy(tid, result);
176
177         heap_get_latest_tid(rel, SnapshotNow, result);
178
179         heap_close(rel, AccessShareLock);
180
181         PG_RETURN_ITEMPOINTER(result);
182 }