mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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
This commit is contained in:
parent
4d29e6dbd0
commit
cc99baa43e
@ -186,35 +186,34 @@ list_length(const List *l)
|
||||
* linitial() than lfirst(): given a List, lsecond() returns the data
|
||||
* in the second list cell.
|
||||
*/
|
||||
|
||||
#define lfirst(lc) ((lc)->ptr_value)
|
||||
#define lfirst_int(lc) ((lc)->int_value)
|
||||
#define lfirst_oid(lc) ((lc)->oid_value)
|
||||
#define lfirst_node(type,lc) castNode(type, lfirst(lc))
|
||||
|
||||
#define linitial(l) lfirst(list_head(l))
|
||||
#define linitial_int(l) lfirst_int(list_head(l))
|
||||
#define linitial_oid(l) lfirst_oid(list_head(l))
|
||||
#define linitial(l) lfirst(list_nth_cell(l, 0))
|
||||
#define linitial_int(l) lfirst_int(list_nth_cell(l, 0))
|
||||
#define linitial_oid(l) lfirst_oid(list_nth_cell(l, 0))
|
||||
#define linitial_node(type,l) castNode(type, linitial(l))
|
||||
|
||||
#define lsecond(l) lfirst(list_second_cell(l))
|
||||
#define lsecond_int(l) lfirst_int(list_second_cell(l))
|
||||
#define lsecond_oid(l) lfirst_oid(list_second_cell(l))
|
||||
#define lsecond(l) lfirst(list_nth_cell(l, 1))
|
||||
#define lsecond_int(l) lfirst_int(list_nth_cell(l, 1))
|
||||
#define lsecond_oid(l) lfirst_oid(list_nth_cell(l, 1))
|
||||
#define lsecond_node(type,l) castNode(type, lsecond(l))
|
||||
|
||||
#define lthird(l) lfirst(list_third_cell(l))
|
||||
#define lthird_int(l) lfirst_int(list_third_cell(l))
|
||||
#define lthird_oid(l) lfirst_oid(list_third_cell(l))
|
||||
#define lthird(l) lfirst(list_nth_cell(l, 2))
|
||||
#define lthird_int(l) lfirst_int(list_nth_cell(l, 2))
|
||||
#define lthird_oid(l) lfirst_oid(list_nth_cell(l, 2))
|
||||
#define lthird_node(type,l) castNode(type, lthird(l))
|
||||
|
||||
#define lfourth(l) lfirst(list_fourth_cell(l))
|
||||
#define lfourth_int(l) lfirst_int(list_fourth_cell(l))
|
||||
#define lfourth_oid(l) lfirst_oid(list_fourth_cell(l))
|
||||
#define lfourth(l) lfirst(list_nth_cell(l, 3))
|
||||
#define lfourth_int(l) lfirst_int(list_nth_cell(l, 3))
|
||||
#define lfourth_oid(l) lfirst_oid(list_nth_cell(l, 3))
|
||||
#define lfourth_node(type,l) castNode(type, lfourth(l))
|
||||
|
||||
#define llast(l) lfirst(list_tail(l))
|
||||
#define llast_int(l) lfirst_int(list_tail(l))
|
||||
#define llast_oid(l) lfirst_oid(list_tail(l))
|
||||
#define llast(l) lfirst(list_last_cell(l))
|
||||
#define llast_int(l) lfirst_int(list_last_cell(l))
|
||||
#define llast_oid(l) lfirst_oid(list_last_cell(l))
|
||||
#define llast_node(type,l) castNode(type, llast(l))
|
||||
|
||||
/*
|
||||
@ -269,6 +268,16 @@ list_nth_cell(const List *list, int n)
|
||||
return &list->elements[n];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the last cell in a non-NIL List.
|
||||
*/
|
||||
static inline ListCell *
|
||||
list_last_cell(const List *list)
|
||||
{
|
||||
Assert(list != NIL);
|
||||
return &list->elements[list->length - 1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the pointer value contained in the n'th element of the
|
||||
* specified list. (List elements begin at 0.)
|
||||
|
Loading…
Reference in New Issue
Block a user