• 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]

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

      

  • 相关阅读:
    git基础使用小记
    MYSQL 安装&配置
    NGINX 安装&配置
    PHP编译安装
    linux基本命令操作
    css清除浮动的8种方法以及优缺点
    简单概括下浏览器事件模型,如何获得资源dom节点
    HTML5新增的表单元素有哪些?
    css 引入的方式有哪些, link和@import的区别是什么
    git与svn的区别
  • 原文地址:https://www.cnblogs.com/lujunfeng/p/6141621.html
Copyright © 2020-2023  润新知