zoukankan      html  css  js  c++  java
  • 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]

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

      

  • 相关阅读:
    ubuntu 启动 重启 停止 apache
    /usr/bin/env: php: No such file or directory 【xunsearch demo项目体验】【已解决】
    安装mezzanine时报:storing debug log for failure【已解决】
    redhat 安装 setuptools【成功】
    SnowNLP:一个处理中文文本的 Python 类库[转]
    Android 了解1G 2G 3G 知识
    Android-体系架构
    Android-bindService远程服务(Aidl)-初步
    Android-SDCard外部存储文件读写
    Android-文件模式
  • 原文地址:https://www.cnblogs.com/lujunfeng/p/6141621.html
Copyright © 2011-2022 走看看