您的位置:首页 > 数据库

PostgreSQL 的 target_list分析(六)

2012-09-11 15:18 239 查看
进一步分析 ColumnRef:

查了一下, 原来 makeColumnRef 就在 gram.y 里面:

static Node *
makeColumnRef(char *colname, List *indirection,
int location, core_yyscan_t yyscanner)
{
/*
* Generate a ColumnRef node, with an A_Indirection node added if there
* is any subscripting in the specified indirection list.  However,
* any field selection at the start of the indirection list must be
* transposed into the "fields" part of the ColumnRef node.
*/
ColumnRef  *c = makeNode(ColumnRef);
int        nfields = 0;
ListCell *l;

c->location = location;
foreach(l, indirection)
{
if (IsA(lfirst(l), A_Indices))
{
A_Indirection *i = makeNode(A_Indirection);
if (nfields == 0)
{
/* easy case - all indirection goes to A_Indirection */
c->fields = list_make1(makeString(colname));
i->indirection = check_indirection(indirection, yyscanner);
}
else
{
/* got to split the list in two */
i->indirection = check_indirection(
list_copy_tail(indirection, nfields),yyscanner);
indirection = list_truncate(indirection, nfields);
c->fields = lcons(makeString(colname), indirection);
}
i->arg = (Node *) c;
return (Node *) i;
}
else if (IsA(lfirst(l), A_Star))
{
/* We only allow '*' at the end of a ColumnRef */
if (lnext(l) != NULL)
parser_yyerror("improper use of \"*\"");
}
nfields++;
}
/* No subscripting, so all indirection gets added to field list */
c->fields = lcons(makeString(colname), indirection);
return (Node *) c;
}


这个

ColumnRef *c = makeNode(ColumnRef);



c->fields = list_make1(makeString(colname)); 将 字段 赋予了 ColumnRef。

makeString 来自于 value.c:

00047 /*
00048  *  makeString
00049  *
00050  * Caller is responsible for passing a palloc'd string.
00051  */
00052 Value *
00053 makeString(char *str)
00054 {
00055     Value      *v = makeNode(Value);
00056
00057     v->type = T_String;
00058     v->val.str = str;
00059     return v;
00060 }


Value 的定义来自于 value.h:

00042 typedef struct Value
00043 {
00044     NodeTag     type;           /* tag appropriately (eg. T_String) */
00045     union ValUnion
00046     {
00047         long        ival;       /* machine integer */
00048         char       *str;        /* string */
00049     }           val;
00050 } Value;


再看 pg_list.h 中的 list_make1:

00142 #define list_make1(x1)              lcons(x1, NIL)


再看 list.c中的 lcons:

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 }
00272


再看 list==NIL 时的 new_list(T_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 }


如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: