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》
PostgreSQL 源码解读 node的模拟实现的更多相关文章
- PostgreSQL源码解读 基础结构 node
一.node节点的定义 源代码路径postgresql-9.2.3/src/include/nodes/nodes.h 在查询解析SQL的查询部分,要用到大量的结构体,许多函数处理的逻辑类似,就是传入 ...
- Spark jdbc postgresql数据库连接和写入操作源码解读
概述:Spark postgresql jdbc 数据库连接和写入操作源码解读,详细记录了SparkSQL对数据库的操作,通过java程序,在本地开发和运行.整体为,Spark建立数据库连接,读取数据 ...
- node.js require() 源码解读
时至今日,Node.js 的模块仓库 npmjs.com ,已经存放了15万个模块,其中绝大部分都是 CommonJS 格式.这种格式的核心就是 require 语句,模块通过它加载.学习 Node. ...
- fastclick.js源码解读分析
阅读优秀的js插件和库源码,可以加深我们对web开发的理解和提高js能力,本人能力有限,只能粗略读懂一些小型插件,这里带来对fastclick源码的解读,望各位大神不吝指教~! fastclick诞生 ...
- AFNetworking 3.0 源码解读(十一)之 UIButton/UIProgressView/UIWebView + AFNetworking
AFNetworking的源码解读马上就结束了,这一篇应该算是倒数第二篇,下一篇会是对AFNetworking中的技术点进行总结. 前言 上一篇我们总结了 UIActivityIndicatorVie ...
- 第二十五课:jQuery.event.trigger的源码解读
本课主要来讲解jQuery.event.trigger的源码解读. trigger = function(event, data, elem, onlyHandlers){ if(elem & ...
- 第二十四课:jQuery.event.remove,dispatch的源码解读
本课还是来讲解一下jQuery是如何实现它的事件系统的.这一课我们先来讲一下jQuery.event.remove的源码解读. remove方法的目的是,根据用户传参,找到事件队列,从里面把匹配的ha ...
- 第二十三课:jQuery.event.add的原理以及源码解读
本课主要来讲解一下jQuery是如何实现它的事件系统的. 我们先来看一个问题: 如果有一个表格有100个tr元素,每个都要绑定mouseover/mouseout事件,改成事件代理的方式,可以节省99 ...
- nodeJS之eventproxy源码解读
1.源码缩影 !(function (name, definition) { var hasDefine = typeof define === 'function', //检查上下文环境是否为AMD ...
随机推荐
- 从PHP5到PHP7的注意事项——PHP7全面删除Mysql扩展支持
PHP删除了一些函数,其中是吓人的是两个: 1. ereg_* 系列的正则函数 2. mysql_* 系列的数据库连接函数 PHP7全面删除Mysql扩展支持,原本的mysql_*系列函数将在mysq ...
- 最小的图灵完备语言——BrainFuck
最小的图灵完备语言--BrainFuck 图灵完备性(Turing completness) 在可计算性理论(computability theory)中,图灵等价指的是:对于两个计算机A和B,如果A ...
- BZOJ 3309 DZY Loves Math ——莫比乌斯反演
枚举$d=gcd(i,j)$ 然后大力反演 ——来自Popoqqq的博客. 然后大力讨论后面的函数的意义即可. http://blog.csdn.net/popoqqq/article/details ...
- POJ 1741 Tree ——点分治
[题目分析] 这貌似是做过第三道以Tree命名的题目了. 听说树分治的代码都很长,一直吓得不敢写,有生之年终于切掉这题. 点分治模板题目.自己YY了好久才写出来. 然后1A了,开心o(* ̄▽ ̄*)ブ ...
- uva 11021
题意:有k只麻球,每只活一天就会死亡,临死之前可能会生出一些新的麻球.具体来说,生i个麻球的概率为pi.给定m,求m天后所有麻球死亡的概率.注意,不足m天时就已经全部死亡的情况也算在内. 分析:由于每 ...
- python 之递归及冒泡排序
一.递归函数 在函数内部,可以调用其他函数,如果一个函数在内部调用本身,这个函数就是递归函数 1.递归的基本原理: 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递 ...
- SLAVEOF以后
当我们想要某个Redis服务器复制另一个服务器时,我们可以在连接这个Redis服务器的客户端上输入“SLAVEOF”命令指定另一个服务器的IP地址和端口号: SLAVEOF <master_ip ...
- 【WEB基础】HTML & CSS 基础入门(5)边框与背景
前面(HTML图片) 漂亮的网页肯定少不了边框与背景的修饰,本篇笔记就是说明如何为网页上的元素设置边框或者背景(背景颜色和背景图片). 之前,先了解一下HTML中的图片元素,因为图片标签的使用非常简单 ...
- codevs——2152 滑雪
2152 滑雪 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场 ...
- Codevs1062路由选择
/* #include<iostream> #include<cstdio> #include<cstring> #define MAXN 301 using na ...