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》

PostgreSQL 源码解读 node的模拟实现的更多相关文章

  1. PostgreSQL源码解读 基础结构 node

    一.node节点的定义 源代码路径postgresql-9.2.3/src/include/nodes/nodes.h 在查询解析SQL的查询部分,要用到大量的结构体,许多函数处理的逻辑类似,就是传入 ...

  2. Spark jdbc postgresql数据库连接和写入操作源码解读

    概述:Spark postgresql jdbc 数据库连接和写入操作源码解读,详细记录了SparkSQL对数据库的操作,通过java程序,在本地开发和运行.整体为,Spark建立数据库连接,读取数据 ...

  3. node.js require() 源码解读

    时至今日,Node.js 的模块仓库 npmjs.com ,已经存放了15万个模块,其中绝大部分都是 CommonJS 格式.这种格式的核心就是 require 语句,模块通过它加载.学习 Node. ...

  4. fastclick.js源码解读分析

    阅读优秀的js插件和库源码,可以加深我们对web开发的理解和提高js能力,本人能力有限,只能粗略读懂一些小型插件,这里带来对fastclick源码的解读,望各位大神不吝指教~! fastclick诞生 ...

  5. AFNetworking 3.0 源码解读(十一)之 UIButton/UIProgressView/UIWebView + AFNetworking

    AFNetworking的源码解读马上就结束了,这一篇应该算是倒数第二篇,下一篇会是对AFNetworking中的技术点进行总结. 前言 上一篇我们总结了 UIActivityIndicatorVie ...

  6. 第二十五课:jQuery.event.trigger的源码解读

    本课主要来讲解jQuery.event.trigger的源码解读. trigger = function(event, data, elem, onlyHandlers){ if(elem & ...

  7. 第二十四课:jQuery.event.remove,dispatch的源码解读

    本课还是来讲解一下jQuery是如何实现它的事件系统的.这一课我们先来讲一下jQuery.event.remove的源码解读. remove方法的目的是,根据用户传参,找到事件队列,从里面把匹配的ha ...

  8. 第二十三课:jQuery.event.add的原理以及源码解读

    本课主要来讲解一下jQuery是如何实现它的事件系统的. 我们先来看一个问题: 如果有一个表格有100个tr元素,每个都要绑定mouseover/mouseout事件,改成事件代理的方式,可以节省99 ...

  9. nodeJS之eventproxy源码解读

    1.源码缩影 !(function (name, definition) { var hasDefine = typeof define === 'function', //检查上下文环境是否为AMD ...

随机推荐

  1. Charles-安装和配置

    一. 安装.破解charles工具 1. 安装压缩包中的charles_setup.exe,安装完成后先不启动charles. 2. 在安装文件中找到crack文件,将文件中的charles.jar拷 ...

  2. STM32F407 窗口看门狗 个人笔记

    窗口看门狗的喂狗时间范围 由框图知: 复位条件是:当且仅当 { 启动位启动 且 { T6为0 (计数器的值减小到0X03F即下限,还没喂狗,即喂狗太晚) 或 计数器的值高于上限时喂狗,即喂狗太早 } ...

  3. CSS+DIV网页样式与布局:第二章:CSS的基本语法

    第二章:CSS的基本语法 一 CSS选择器(所有的HTML语言中的标记都是通过不同的css选择器进行控制的).用户只需要 通过选择器对不同的HTML标签进行控制,并赋予各种样式声明,即可实现各种效果. ...

  4. java中传入一个数或字符串或数组进行反转

    //将一个数用递归反转--利用余数 public static void inverse(int n) { System.out.print(n % 10); if (n >= 10) inve ...

  5. 【Luogu】P3856公共子串(DP)

    题目链接 DP.设last[i][j]是第i个串字符'j'所在的最后的位置,f[i][j][k]是第一个串匹配到i,第二个串匹配到j,第三个串匹配到k,最多的公共子串数. 那么我们三重循环i.j.k, ...

  6. 论文笔记:Ten years of pedestrian detection, what have we learned?

    最近正在研究行人检测,学习了一篇2014年发表在ECCV上的一篇综述性的文章,是对行人检测过去十年的一个回顾,从dataset,main approaches的角度分析了近10年的40多篇论文提出的方 ...

  7. Garbage First介绍

    本文摘自<构建高性能的大型分布式Java应用>一书,Garbage First简称G1,它的目标是要做到尽量减少GC所导致的应用暂停的时间,让应用达到准实时的效果,同时保持JVM堆空间的利 ...

  8. PHP简单留言板

    <?php header("Content-Type:text/html;charset=utf8"); $filename = "message.txt" ...

  9. msp430项目编程54

    msp430综合项目---扩展项目四54 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结

  10. Python入门--6--今天抄袭人家一篇日志--numpy这个

    Numpy NumPy的主要对象是同种元素的多维数组. 这是一个所有元素都是同一类型.通过一个正整数元祖索引的元素表格(通常元素都是数字) 在Numpy中维度(dimensions)叫做:轴 轴的个数 ...