postgres创建表的过程以及部分源码分析
背景:修改pg内核,在创建表时,表名不能和当前的用户名同名。
首先我们知道DefineRelation此函数是最终创建表结构的函数,最主要的参数是CreateStmt这个结构,该结构如下
typedef struct CreateStmt
{
NodeTag type;
RangeVar *relation; /* relation to create */
List *tableElts; /* column definitions (list of ColumnDef) */
List *inhRelations; /* relations to inherit from (list of
* inhRelation) */
TypeName *ofTypename; /* OF typename */
List *constraints; /* constraints (list of Constraint nodes) */
List *options; /* options from WITH clause */
OnCommitAction oncommit; /* what do we do at COMMIT? */
char *tablespacename; /* table space to use, or NULL */
bool if_not_exists; /* just do nothing if it already exists? */
} CreateStmt;
结构中relation中包含了catalogname,schemaname,relname此时的relname就能够顺利的拿到。
tableElts 这个list定义了表结构中的所有列名,如若想增加个非隐藏列,可以append进去。
下图是创建一个简单表,PG内部函数的调用过程:

在PG backend上敲入的sql,入口函数都是exec_simple_query,把这串sql解析,重写后生产执行计划。
附带一个PG内核删除的函数,将query结构反解析出sql的函数
char *
deparse_query_def(Query *query)
{
StringInfoData buf; initStringInfo(&buf);
get_query_def(query, &buf, NIL, NULL,
PRETTYFLAG_INDENT, WRAP_COLUMN_DEFAULT, 0); return buf.data;
}
如果想很好的看清query以及subquery重写以后的任务是什么,可以将此函数编译进pg内核。
在ProcessUtility这个过程中有钩子函数可以挂接,可以根据nodeTag(parseTree)的类型来分别进行处理,例如cstore_fdw中T_DropStmt这种操作的时候,将物理文件删除
这个钩子的用处还可以控制某些操作加入你想的内容。
我们可以在ProcessUtilitySlow这个函数进行内核修改,加入对当前用户名获取,并从CreateStmt结构中的relname进行对比,然后控制是否创建表或者进行报错信息。
获取当前用户名如下
Datum
current_user(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId()))));
}
此函数是PG的内部函数,使用效果是:
postgres=# select CURRENT_USER;
current_user
--------------
postgres
(1 row)
按照这样的做法就能够完成背景下的内容了。
PS:通常还有几个搭配函数使用->DefineRelation->CommandCounterIncrement->transformRelOptions
->heap_reloptions->NewRelationCreateToastTable[AlterTableCreateToastTable]
注:未经同意,不得转载!
postgres创建表的过程以及部分源码分析的更多相关文章
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- Spring AOP 源码分析 - 拦截器链的执行过程
1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...
- Spring AOP 源码分析 - 创建代理对象
1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...
- Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...
- Java源码分析:关于 HashMap 1.8 的重大更新(转载)
http://blog.csdn.net/carson_ho/article/details/79373134 前言 HashMap 在 Java 和 Android 开发中非常常见 而HashMap ...
- MyBatis 源码分析 - 插件机制
1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
随机推荐
- 警告: [unchecked] 对作为原始类型IScheme的成员的write(TProt ocol,T)的调用未经过检查
jdk 从8 改成了7 就好了! 或者, 修改源码, 每个响应的地方加上 surppressingWarnings xxx , 或者使用 请使用 -Xlint:unchecked 重新编译. 参照 h ...
- Win下必备利器之Cmder
诚言,对于开发码字者,Mac和Linux果断要比Windows更贴心;但只要折腾下,Windows下也是有不少利器的.之前就有在Windows下效率必备软件一文中对此做了下记载:其虽没oh-my-zs ...
- Jquery
使用时jquery先引进jquery文件包 <script src="jquery-1.11.2.min.js"></script> 一个页面有多个文件jq ...
- 开发node桌面级应用工具:apk转化epub
随着苹果ibooks对国内的开放,最近接了个麻烦的需求: 把现有的APK转化支持苹果ibooks电子书的epub格式 apk,基本都知道就是安卓的应用程序 epub,是ibooks支持的电子书格式 ( ...
- 窥探Vue.js 2.0
title: 窥探Vue.js2.0 date: 2016-09-27 10:22:34 tags: vue category: 技术总结 --- 窥探Vue.js2.0 令人兴奋的Vue.js 2. ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox
系列目录 https://yunpan.cn/cZVeSJ33XSHKZ 访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...
- Hawk 4.3 转换器
转换器是最为常用的一种类型,当然它的使用也是最复杂的. 转换器有三种子类型: A:单文档->单文档:例如仅将某一列的字符提取出来 B:单文档->多文档:典型的如从爬虫转换,每一行url都可 ...
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...
- linq to js使用汇总
用途:方便js操作查询json数据. 下载网址:http://jslinq.codeplex.com/ 使用方法:只需要引用linq.js即可. 查询方法: 一.where查询 var myList ...
- Java Map hashCode深究
[Java心得总结七]Java容器下——Map 在自己总结的这篇文章中有提到hashCode,但是没有细究,今天细究整理一下hashCode相关问题 1.hashCode与equals 首先我们都知道 ...