PostgreSQL中的 lcons

前面我们说过了 listmake1其实是特殊的 lcons,

而lcons 函数位于 list.c 中。

00259 lcons(void *datum, List *list)

00260 {

00261     Assert(IsPointerList(list));

00262 

00263     if (list == NIL)

00264         list = new_list(T_List);

00265     else

00266         new_head_cell(list);

00267 

00268     lfirst(list->head) = datum;

00269     check_list_invariants(list);

00270     return list;

00271 }    

 看 gram.y 中的 target_list 的定义:

target_list:                                    

            target_el                { $$ = list_make1($1); }        

            | target_list ',' target_el                { $$ = lappend($1, $3); }        

        ;  

listmake1($1) 就是,通过 lcons来建立一个空的List, 其head 指向 $1。

我们可以看到 ,当 lcons的第二个参数为空的时候,会执行 new_list 操作,创建一个只有头的list

00063 new_list(NodeTag type)

00064 {

00065 List *new_list;

00066 ListCell *new_head;

00067 

00068 new_head = (ListCell *) palloc(sizeof(*new_head));

00069 new_head->next = NULL;

00070 /* new_head->data is left undefined! */

00071 

00072 new_list = (List *) palloc(sizeof(*new_list));

00073 new_list->type = type;

00074 new_list->length = 1;

00075 new_list->head = new_head;

00076 new_list->tail = new_head;

00077 

00078 return new_list;

00079 }

从上面 new_list里,可以看到,它创建了一个 ListCell(虽然是空的)。

然后,new_list 的头和尾首先都指向这个 ListCell。

再然后,这个新生成的 list, 其 尾部指向 datum 。
也就是 指向了 makeNode(ResTarget)的 ResTarget类型

也就是下图:

PostgreSQL中的 lcons

 

今后,再进一步分析更复杂的情形。

你可能感兴趣的:(PostgreSQL)