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_path
(src/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_path
:spa
在 RangeVarGetCreationNamespace
、RelnameGetRelid
、TypenameGetTypid
这类位置会调用它,发生在:建立没有指定schema的对象、按名字查找对象、肯定对象可见性等等行为时。这些均可以在 src/backend/catalog/namespace.c
中看到,再也不赘述。code
三、从新计算的逻辑对象
首先将 namespace_search_path
按逗号切分红多个元素。ip
有两个特殊名字的处理:$user
和 pg_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下建表看成临时表。