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]

注:未经同意,不得转载!

  

时间: 2024-11-04 18:35:23

postgres创建表的过程以及部分源码分析的相关文章

struts--token防止表单重复提交(源码分析)

表单重复提交 1.造成重复提交主要的两个原因: (1)        服务器处理时间久.当用户在表单中填完信息,点击"提交"按钮后,由于服务器反应时间过长没能及时看到响应信息,或者出于其它目的,再次点击"提交"按钮,从而导致在服务器端接收到两条或多条相同的信息. (2)      forward跳转引起的重复提交.当用户将信息提交到服务器,服务器响应采用forward方式调转到下一个页面后,此时地址栏中显示的是上个页面的URL,若刷新当前页面,浏览器会将再次提交用户

MyBatis 源码分析 - 插件机制

1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 MyBatis 为例,我们可基于 MyBatis 插件机制实现分页.分表,监控等功能.由于插件和业务无关,业务也无法感知插件的存在.因此可以无感植入插件,在无形中增强功能. 开发 MyBatis 插件需要对 MyBatis 比较深了解才行,一般来说最好能够掌握 MyBatis 的源码,门槛相对较高.本篇

源码分析 HashMap 1.8

1.0 数据结构 2.0 存储流程 3.0 数组元素 & 链表节点的实现类 HashMap中的数组元素 & 链表节点 采用 Node类 实现,与jdk1.7相比只是把Entry换了个名字 HashMap中的红黑树节点 采用 TreeNode 类 实现 /** * 红黑树节点 实现类:继承自LinkedHashMap.Entry<K,V>类 */ static final class TreeNode<K,V> extends LinkedHashMap.Entry&

Dubbo 源码分析 - 自适应拓展原理

1.原理 我在上一篇文章中分析了 Dubbo 的 SPI 机制,Dubbo SPI 是 Dubbo 框架的核心.Dubbo 中的很多拓展都是通过 SPI 机制进行加载的,比如 Protocol.Cluster.LoadBalance 等.有时,有些拓展并非想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载.这听起来有些矛盾.拓展未被加载,那么拓展方法就无法被调用(静态方法除外).拓展方法未被调用,就无法进行加载,这似乎是个死结.不过好在也有相应的解决办法,通过代理模式就可

Dialog源码分析

目录介绍 1.简单用法 2.AlertDialog源码分析 2.1 AlertDialog.Builder的构造方法 2.2 通过AlertDialog.Builder对象设置属性 2.3 builder.create方法 2.4 看看create方法中的P.apply(dialog.mAlert)源码 2.5 看看AlertDialog的show方法 3.Dialog源码分析 3.1 Dialog的构造方法 3.2 Dialog生命周期 3.3 Dialog中show方法展示弹窗 3.4 Di

【spring源码分析】IOC容器初始化(总结)

前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正的bean对象. 总结 [spring源码分析]IOC容器初始化(一):主要分析了Spring是如何解析占位符以及BeanFactory的最终实现类DefaultListableBeanFactory. [spring源码分析]IOC容器初始化(二):以loadBeanDefinitions函数为切

【React源码分析】组件通信、refs、key和ReactDOM

React源码系列文章,请多支持:React源码分析1 - 组件和对象的创建(createClass,createElement)React源码分析2 - React组件插入DOM流程React源码分析3 - React生命周期详解React源码分析4 - setState机制React源码分析5 -- 组件通信,refs,key,ReactDOMReact源码分析6 - React合成事件系统 1 组件间通信 父组件向子组件通信 React规定了明确的单向数据流,利用props将数据从父组件传

Mesos源码分析

Mesos源码分析(1): Mesos的启动过程总论 Mesos源码分析(2): Mesos Master的启动之一 Mesos源码分析(3): Mesos Master的启动之二 Mesos源码分析(4) Mesos Master的启动之三 Mesos源码分析(5): Mesos Master的启动之四 Mesos源码分析(6): Mesos Master的初始化 Mesos源码分析(7): Mesos-Slave的启动 Mesos源码分析(8): Mesos-Slave的初始化 Mesos源

apache kafka源码分析走读-Producer分析

apache kafka中国社区QQ群:162272557 producer的发送方式剖析 Kafka提供了Producer类作为java producer的api,该类有sync和async两种发送方式. sync架构图 async架构图 调用流程如下: 代码流程如下: Producer:当new Producer(new ProducerConfig()),其底层实现,实际会产生两个核心类的实例:Producer.DefaultEventHandler.在创建的同时,会默认new一个Prod