Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Improve castNode notation by introducing list-extraction-specific variants.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Apr 2017 17:51:29 +0000 (13:51 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Apr 2017 17:51:29 +0000 (13:51 -0400)
This extends the castNode() notation introduced by commit 5bcab1114 to
provide, in one step, extraction of a list cell's pointer and coercion to
a concrete node type.  For example, "lfirst_node(Foo, lc)" is the same
as "castNode(Foo, lfirst(lc))".  Almost half of the uses of castNode
that have appeared so far include a list extraction call, so this is
pretty widely useful, and it saves a few more keystrokes compared to the
old way.

As with the previous patch, back-patch the addition of these macros to
pg_list.h, so that the notation will be available when back-patching.

Patch by me, after an idea of Andrew Gierth's.

Discussion: https://postgr.es/m/14197.1491841216@sss.pgh.pa.us

src/include/nodes/pg_list.h

index 77b50ff1c74608a80242dd3f37ba1c4224911ff5..00ab5ae968b032f2e693bfda31799b92cf823cfe 100644 (file)
@@ -106,26 +106,32 @@ list_length(const List *l)
 #define lfirst(lc)             ((lc)->data.ptr_value)
 #define lfirst_int(lc)         ((lc)->data.int_value)
 #define lfirst_oid(lc)         ((lc)->data.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_node(type,l)  castNode(type, linitial(l))
 
 #define lsecond(l)             lfirst(lnext(list_head(l)))
 #define lsecond_int(l)         lfirst_int(lnext(list_head(l)))
 #define lsecond_oid(l)         lfirst_oid(lnext(list_head(l)))
+#define lsecond_node(type,l)   castNode(type, lsecond(l))
 
 #define lthird(l)              lfirst(lnext(lnext(list_head(l))))
 #define lthird_int(l)          lfirst_int(lnext(lnext(list_head(l))))
 #define lthird_oid(l)          lfirst_oid(lnext(lnext(list_head(l))))
+#define lthird_node(type,l)        castNode(type, lthird(l))
 
 #define lfourth(l)             lfirst(lnext(lnext(lnext(list_head(l)))))
 #define lfourth_int(l)         lfirst_int(lnext(lnext(lnext(list_head(l)))))
 #define lfourth_oid(l)         lfirst_oid(lnext(lnext(lnext(list_head(l)))))
+#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_node(type,l)     castNode(type, llast(l))
 
 /*
  * Convenience macros for building fixed-length lists
@@ -204,6 +210,7 @@ extern ListCell *list_nth_cell(const List *list, int n);
 extern void *list_nth(const List *list, int n);
 extern int list_nth_int(const List *list, int n);
 extern Oid list_nth_oid(const List *list, int n);
+#define list_nth_node(type,list,n) castNode(type, list_nth(list, n))
 
 extern bool list_member(const List *list, const void *datum);
 extern bool list_member_ptr(const List *list, const void *datum);