zoukankan      html  css  js  c++  java
  • PostgreSQL 的 target_list分析(六)

    进一步分析 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 }

    如下图:

  • 相关阅读:
    面试题47题
    深度学习面试
    神经网络训练中的梯度消失与梯度爆炸
    Softmax函数与交叉熵
    sourceTree 添加 ssh key 方法
    request.form()和request()的区别
    C#中Request.ServerVariables详细说明及代理
    Page_Load事件与IsPostBack属性
    CSS中position的absolute和relative用法
    读取游标
  • 原文地址:https://www.cnblogs.com/gaojian/p/2680251.html
Copyright © 2011-2022 走看看