Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cc99baa

Browse files
committed
Improve pg_list.h's linitial(), lsecond() and co macros
Prior to this commit, the linitial(), lsecond(), lthird(), lfourth() macros and their int and Oid list cousins would call their corresponding inlined function to fetch the cell of interest. Those inline functions were kind enough to return NULL if the particular cell did not exist. Unfortunately, the care that these functions took was of no relevance to the calling macros as they proceeded to directly dereference the returned value without any regard to whether that value was NULL or not. If it had been, we'd have segfaulted. Of course, the fact that we would have segfaulted on misuse of these macros just goes to prove that nobody is relying on the empty or list too small checks. So here we just get rid of those checks completely. The existing inline functions have been left alone as someone may be using those directly. We just replace the call within each macro to use list_nth_cell(). For the llast*() case we require a new list_last_cell() inline function to get away from the multiple evaluation hazard that we'd get if we fetched ->length on the macro's parameter. Author: David Rowley Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAApHDvpo1zj9KhEpU2cCRZfSM3Q6XGdhzuAS2v79PH7WJBkYVA@mail.gmail.com
1 parent 4d29e6d commit cc99baa

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/include/nodes/pg_list.h

+25-16
Original file line numberDiff line numberDiff line change
@@ -186,35 +186,34 @@ list_length(const List *l)
186186
* linitial() than lfirst(): given a List, lsecond() returns the data
187187
* in the second list cell.
188188
*/
189-
190189
#define lfirst(lc) ((lc)->ptr_value)
191190
#define lfirst_int(lc) ((lc)->int_value)
192191
#define lfirst_oid(lc) ((lc)->oid_value)
193192
#define lfirst_node(type,lc) castNode(type, lfirst(lc))
194193

195-
#define linitial(l) lfirst(list_head(l))
196-
#define linitial_int(l) lfirst_int(list_head(l))
197-
#define linitial_oid(l) lfirst_oid(list_head(l))
194+
#define linitial(l) lfirst(list_nth_cell(l, 0))
195+
#define linitial_int(l) lfirst_int(list_nth_cell(l, 0))
196+
#define linitial_oid(l) lfirst_oid(list_nth_cell(l, 0))
198197
#define linitial_node(type,l) castNode(type, linitial(l))
199198

200-
#define lsecond(l) lfirst(list_second_cell(l))
201-
#define lsecond_int(l) lfirst_int(list_second_cell(l))
202-
#define lsecond_oid(l) lfirst_oid(list_second_cell(l))
199+
#define lsecond(l) lfirst(list_nth_cell(l, 1))
200+
#define lsecond_int(l) lfirst_int(list_nth_cell(l, 1))
201+
#define lsecond_oid(l) lfirst_oid(list_nth_cell(l, 1))
203202
#define lsecond_node(type,l) castNode(type, lsecond(l))
204203

205-
#define lthird(l) lfirst(list_third_cell(l))
206-
#define lthird_int(l) lfirst_int(list_third_cell(l))
207-
#define lthird_oid(l) lfirst_oid(list_third_cell(l))
204+
#define lthird(l) lfirst(list_nth_cell(l, 2))
205+
#define lthird_int(l) lfirst_int(list_nth_cell(l, 2))
206+
#define lthird_oid(l) lfirst_oid(list_nth_cell(l, 2))
208207
#define lthird_node(type,l) castNode(type, lthird(l))
209208

210-
#define lfourth(l) lfirst(list_fourth_cell(l))
211-
#define lfourth_int(l) lfirst_int(list_fourth_cell(l))
212-
#define lfourth_oid(l) lfirst_oid(list_fourth_cell(l))
209+
#define lfourth(l) lfirst(list_nth_cell(l, 3))
210+
#define lfourth_int(l) lfirst_int(list_nth_cell(l, 3))
211+
#define lfourth_oid(l) lfirst_oid(list_nth_cell(l, 3))
213212
#define lfourth_node(type,l) castNode(type, lfourth(l))
214213

215-
#define llast(l) lfirst(list_tail(l))
216-
#define llast_int(l) lfirst_int(list_tail(l))
217-
#define llast_oid(l) lfirst_oid(list_tail(l))
214+
#define llast(l) lfirst(list_last_cell(l))
215+
#define llast_int(l) lfirst_int(list_last_cell(l))
216+
#define llast_oid(l) lfirst_oid(list_last_cell(l))
218217
#define llast_node(type,l) castNode(type, llast(l))
219218

220219
/*
@@ -269,6 +268,16 @@ list_nth_cell(const List *list, int n)
269268
return &list->elements[n];
270269
}
271270

271+
/*
272+
* Return the last cell in a non-NIL List.
273+
*/
274+
static inline ListCell *
275+
list_last_cell(const List *list)
276+
{
277+
Assert(list != NIL);
278+
return &list->elements[list->length - 1];
279+
}
280+
272281
/*
273282
* Return the pointer value contained in the n'th element of the
274283
* specified list. (List elements begin at 0.)

0 commit comments

Comments
 (0)