]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/tid.c
Second round of fmgr changes: triggers are now invoked in new style,
[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-2000, PostgreSQL, Inc
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.17 2000/05/29 01:59:08 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 "utils/builtins.h"
23
24 #define LDELIM                  '('
25 #define RDELIM                  ')'
26 #define DELIM                   ','
27 #define NTIDARGS                2
28
29 /* ----------------------------------------------------------------
30  *              tidin
31  * ----------------------------------------------------------------
32  */
33 ItemPointer
34 tidin(const char *str)
35 {
36         const char *p,
37                            *coord[NTIDARGS];
38         int                     i;
39         ItemPointer result;
40
41         BlockNumber blockNumber;
42         OffsetNumber offsetNumber;
43
44         if (str == NULL)
45                 return NULL;
46
47         for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
48                 if (*p == DELIM || (*p == LDELIM && !i))
49                         coord[i++] = p + 1;
50
51         /* if (i < NTIDARGS - 1) */
52         if (i < NTIDARGS)
53         {
54                 elog(ERROR, "%s invalid tid format", str);
55                 return NULL;
56         }
57
58         blockNumber = (BlockNumber) atoi(coord[0]);
59         offsetNumber = (OffsetNumber) atoi(coord[1]);
60
61         result = (ItemPointer) palloc(sizeof(ItemPointerData));
62
63         ItemPointerSet(result, blockNumber, offsetNumber);
64
65         return result;
66 }
67
68 /* ----------------------------------------------------------------
69  *              tidout
70  * ----------------------------------------------------------------
71  */
72 char *
73 tidout(ItemPointer itemPtr)
74 {
75         BlockNumber blockNumber;
76         OffsetNumber offsetNumber;
77         BlockId         blockId;
78         char            buf[32];
79         char       *str;
80         static char *invalidTid = "()";
81
82         if (!itemPtr || !ItemPointerIsValid(itemPtr))
83         {
84                 str = palloc(strlen(invalidTid));
85                 strcpy(str, invalidTid);
86                 return str;
87         }
88
89         blockId = &(itemPtr->ip_blkid);
90
91         blockNumber = BlockIdGetBlockNumber(blockId);
92         offsetNumber = itemPtr->ip_posid;
93
94         sprintf(buf, "(%d,%d)", blockNumber, offsetNumber);
95
96         str = (char *) palloc(strlen(buf) + 1);
97         strcpy(str, buf);
98
99         return str;
100 }
101
102 /*****************************************************************************
103  *       PUBLIC ROUTINES                                                                                                                 *
104  *****************************************************************************/
105
106 bool
107 tideq(ItemPointer arg1, ItemPointer arg2)
108 {
109         if ((!arg1) || (!arg2))
110                 return false;
111
112         return (BlockIdGetBlockNumber(&(arg1->ip_blkid)) ==
113                         BlockIdGetBlockNumber(&(arg2->ip_blkid)) &&
114                         arg1->ip_posid == arg2->ip_posid);
115 }
116
117 bool
118 tidne(ItemPointer arg1, ItemPointer arg2)
119 {
120         if ((!arg1) || (!arg2))
121                 return false;
122         return (BlockIdGetBlockNumber(&(arg1->ip_blkid)) !=
123                         BlockIdGetBlockNumber(&(arg2->ip_blkid)) ||
124                         arg1->ip_posid != arg2->ip_posid);
125 }
126
127 text *
128 tid_text(ItemPointer tid)
129 {
130         char       *str;
131
132         if (!tid)
133                 return (text *) NULL;
134         str = tidout(tid);
135
136         return textin(str);
137 }       /* tid_text() */
138
139 ItemPointer
140 text_tid(const text *string)
141 {
142         ItemPointer result;
143         char       *str;
144
145         if (!string)
146                 return (ItemPointer) 0;
147
148         str = textout((text *) string);
149         result = tidin(str);
150         pfree(str);
151
152         return result;
153 }       /* text_tid() */
154
155
156 /*
157  *      Functions to get latest tid of a specified tuple.
158  *      Maybe these implementations is moved
159  *      to another place
160 */
161 #include <utils/relcache.h>
162 ItemPointer
163 currtid_byreloid(Oid reloid, ItemPointer tid)
164 {
165         ItemPointer result = NULL,
166                                 ret;
167         Relation        rel;
168
169         result = (ItemPointer) palloc(sizeof(ItemPointerData));
170         ItemPointerSetInvalid(result);
171         if (rel = heap_open(reloid, AccessShareLock), rel)
172         {
173                 ret = heap_get_latest_tid(rel, SnapshotNow, tid);
174                 if (ret)
175                         ItemPointerCopy(ret, result);
176                 heap_close(rel, AccessShareLock);
177         }
178         else
179                 elog(ERROR, "Relation %u not found", reloid);
180
181         return result;
182 }       /* currtid_byreloid() */
183
184 ItemPointer
185 currtid_byrelname(const text *relname, ItemPointer tid)
186 {
187         ItemPointer result = NULL,
188                                 ret;
189         char       *str;
190         Relation        rel;
191
192         if (!relname)
193                 return result;
194
195         str = textout((text *) relname);
196
197         result = (ItemPointer) palloc(sizeof(ItemPointerData));
198         ItemPointerSetInvalid(result);
199         if (rel = heap_openr(str, AccessShareLock), rel)
200         {
201                 ret = heap_get_latest_tid(rel, SnapshotNow, tid);
202                 if (ret)
203                         ItemPointerCopy(ret, result);
204                 heap_close(rel, AccessShareLock);
205         }
206         else
207                 elog(ERROR, "Relation %s not found", textout((text *) relname));
208         pfree(str);
209
210         return result;
211 }       /* currtid_byrelname() */