• PostgreSQL 源码解读 node的模拟实现


     

    node的实现是PostgreSQL的查询解析的基础,实现的关键是两个宏,makeNode和newNode。其他节点继承自Node节点,如果增加新的结构体,需要添加NodeTag中添加对应的枚举值,并在equal和nodetoString中添加对于的处理代码。当结构体少是很容易处理,如果结构体过多,维护会比较麻烦。PostgreSQL中大约有300个继承自node的结构体,写代码的人真是需要相当的勇气和毅力呀。

     

    #include <iostream>

    #include <string.h>

    #include <assert.h>

    #include <stdlib.h>

    #include <stdio.h>

    using namespace std;

     

    enum NodeTag

    {

        T_Stmt,

        T_Value

    };

     

    typedef struct Node

    {

        NodeTag type;

    }Node;

     

    Node *newNodeMacroHolder ;

    #define newNode(size, tag)

        (

             assert((size) >= sizeof(Node)),        /* need the tag, at least */

             newNodeMacroHolder = (Node *) malloc(size),

             newNodeMacroHolder->type = (tag),

             newNodeMacroHolder

        )

     

    #define makeNode(_type_) ((_type_ *)newNode(sizeof(_type_),T_##_type_))

    #define nodeTag(nodeptr) (((const Node *)(nodeptr))->type)

     

    typedef struct Stmt

    {

        NodeTag type;

        char *text;

    }Stmt;

    typedef struct Value

    {

        NodeTag type;

        long val;

    }Value;

     

    bool equal(void *a,void *b)

    {

        if(a == b)

            return true;

        if (a == NULL || b == NULL)

            return false;

        if(nodeTag(a) != nodeTag(b))

            return false;

     

        switch(nodeTag(a)){

            case T_Stmt:

                return strcmp(((const Stmt*)a)->text,((const Stmt *)b)->text)==0? true:false;

            case T_Value:

                return ((const Value *)a)->val==((const Value *)b)->val;

            default:

                cout<<"error:unknown type"<<endl;

        }

     

        return false;

    }

    char * nodetoString(void *obj)

    {

        char *r =(char *)malloc(1024);

     

        if (obj == NULL){

            strcpy(r,"<>");

        }

     

        switch(nodeTag(obj)){

            case T_Stmt:

                sprintf(r,"<Stmt:%s>",((const Stmt *)obj)->text);

                break;

            case T_Value:

                sprintf(r,"<Value:%ld>",((const Value *)obj)->val);

                break;

            default:

                strcpy(r,"<unknown node type>");

        }

     

        return r;

    }

     

    int main(int argc,char *argv[])

    {

        Stmt *s= makeNode(Stmt);

        if(s){

            char str[]="select * from a";

            s->text=str;

        }

            

        Stmt *t= makeNode(Stmt);

        if(t){

            char str[]="select * from b";

            t->text=str;

        }

        Value *v=makeNode(Value);

        if(v){

            v->val=100;

        }

     

        cout<<"t->text:"<<t->text<<endl;

        

        cout<<"equal:"<<equal(s,t)<<endl;

     

        cout<<nodetoString(t)<<endl;

     

        free(s);

        free(t);

        free(v);

        return 0;

    }

     

    如果准备使用C语言来实现node结构体的话,尤其是准备采用gcc编译的话,要注意将newNode的宏设置为

    /* 针对gcc版本的newNode */

    #define newNode(size, tag)

    ({    Node *_result;

        AssertMacro((size) >= sizeof(Node));/* 检测申请的内存大小,>>=sizeof(Node) */ 

        _result = (Node *) palloc0fast(size); /* 申请内存 */

        _result->type = (tag); /*设置TypeTag */ 

        _result; /*返回值*/

    })

     

    参见我的另一篇笔记《PostgreSQL源码解读 基础结构 node

  • 相关阅读:
    分类和预测
    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)
    字符串匹配的KMP算法
    灰度共生矩阵提取纹理特征源码
    redis永不过期,保留最新5条数据,StringUtils.join()等总结
    Session问题以及解决方案
    spring boot 配置 log4j2
    每日知识记载总结54
    spring cloud踩坑指南
    每日知识记载总结53
  • 原文地址:https://www.cnblogs.com/chenxueyou/p/3418494.html
Copyright © 2020-2023  润新知