PostgreSQL参数search_path影响及做用

search_path稍微熟悉PG就会用到,用法这里就没必要讲,本篇主要讲它在程序里怎样处理。后端

一、GUC参数定义bash

这是个 config_string 参数ide

{
		{"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT,
			gettext_noop("Sets the schema search order for names that are not schema-qualified."),
			NULL,
			GUC_LIST_INPUT | GUC_LIST_QUOTE
		},
		&namespace_search_path,
		"\"$user\", public",
		check_search_path, assign_search_path, NULL
	},

设置了两个hook,赋值和检查。assign_search_pathsrc/backend/catalog/namespace.c)只是简单标记参数失效,下次使用时须要再次计算。函数

void
assign_search_path(const char *newval, void *extra)
{
	/*
	 * We mark the path as needing recomputation, but don't do anything until
	 * it's needed.  This avoids trying to do database access during GUC
	 * initialization, or outside a transaction.
	 */
	baseSearchPathValid = false;
}

二、从新计算的时机oop

函数 recomputeNamespacePath(void) 从新计算GUC定义的 namespace_search_pathspa

RangeVarGetCreationNamespaceRelnameGetRelidTypenameGetTypid 这类位置会调用它,发生在:建立没有指定schema的对象、按名字查找对象、肯定对象可见性等等行为时。这些均可以在 src/backend/catalog/namespace.c 中看到,再也不赘述。code

三、从新计算的逻辑对象

首先将 namespace_search_path 按逗号切分红多个元素。ip

有两个特殊名字的处理:$userpg_temp,前者若是存在与当前用户同名的schema则加入到搜索路径中,不存则没有任何影响;后者若是当先后端对应的临时schema已建立,加入搜索路径,未建立则标记(activeTempCreationPending)下次使用搜索路径前须要先建立,很少讲这个。文档

其它按名字查找各自的OID,找不到则跳过,最终造成一个搜索链表。至此,这里做为建立对象使用的第一个schema位置,接下来是搜索路径的补足。

不少系统定义都是在 pg_catalog 中,因此:

if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
		oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);

若是定义中没有包含它,加到最前边。

一样,临时schema已经建立且没有包含,再加到最前边,也就是说它是在 pg_catalog 前的。

以默认设置:"$user", public 为例,若是不存在同名schema,结果就是不指定scheme时,对象建立在public下,搜索时则先pg_catalog 后 public。

四、系统模式 pg_catalog

看完上边的逻辑,试试把 pg_catalog 加到第一位置会怎样,它会变成默认建立schema:

flying=# set search_path = pg_catalog,public;
SET
flying=# create table t();
ERROR:  permission denied to create "pg_catalog.t"
DETAIL:  System catalog modifications are currently disallowed.
flying=#

在系统模式下建表是不容许的。

五、临时模式

pg_temp 放在第一位置:

flying=# set search_path = pg_temp,public;
SET
flying=# create table t();
CREATE TABLE
flying=# select relpersistence from pg_class where relname='t';
 relpersistence
----------------
 t
(1 row)

flying=# \d+ t
                                  Table "pg_temp_3.t"
 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+------+-----------+----------+---------+---------+--------------+-------------

建立的是一个临时表,根据文档这是对的,在pg_temp下建表看成临时表。

相关文章
相关标签/搜索