nyuuzyou/wikis huggingface dataset:
90ReleaseSchedule

== Website Preparation ==
The following changes all need to be prepared so that they can go out in one commit at the appropriate time. Please put your name next to items which you can claim, and mark them when done.
* Home Page
** Call Box should say "9.0 Release" and have appropriate links -- Devrim DONE
** Latest Releases should rotate to 9.0 and 8.0 should drop off -- Devrim DONE
* News
**Write Internal announcement for News Item and Submit -- Josh WRITTEN
**Check News Item -- CHECKED (Thom)
*developers/beta:
**Needs to change to "Beta is over" page -- Devrim DONE
*about/press:
**Gather all presskits and translations -- Josh DONE, RO pending
***Correct presskits -- Josh DONE
**Create TOC for about/press -- Josh, DONE
*about
**Feature Matrix: "9.0dev" should change to "9.0" -- Devrim ALREADY DONE
*Documentation
**"9.0 beta" should change to "9.0" -- Devrim DONE
**"What's New" link should point to 9.0 release notes -- Devrim DONE
*External
**Submit Release to PRWire -- Josh (possibly not doing this year, may do BusinessWire instead -- SCHEDULED)
**Update FreshMeat
**Update SourceForge
== Scheduled Deployments ==
Here's the things which need to be done, and the times they need to be done. Given issues in the past, we should have a responsible and a backup person for each task. The schedule below assumes a Sept. 20 release. Please add tasks as appropriate.
UTC Time 	EDT Time 	Task 	Person 	Backup 	Done?
9/17 04:00	9/17 00:00	Source Tarballs uploaded 	Marc 	 	Y
9/18 01:00	9/17 21:00	Tarballs checkedFinal turnback point 	Packagers 	 	Y
9/18 01:00	9/17 21:00	Go-ahead notice sent to RCsand to advance press 	Josh 	Selena 	Y
9/18 18:00	9/18 14:00	Packages bundled and uploaded 	Packagers 	 	Y
9/18 21:00	9/18 17:00	Move FTP files to main FTP 	Marc 	 	Y
9/20 11:00	9/20 07:00	Load new docs into website database 	Devrim 	 	Y
9/20 11:15	9/20 07:15	Merge changes into website, along with presskits.	Devrim 	 	Y
9/20 11:15	9/20 07:15	Approve news item 	Devrim 	 	Y
9/20 11:30	9/20 07:30	Schedule website rebuild, inc. docs 	Devrim 	 	Y
9/20 14:00	9/20 10:00	Send out pgsql-announce 	Josh 	Selena 	Y
9/20 14:00	9/20 10:00	Send out notices to press 	Josh, RCs 	Selena 	
9/20 19:00	9/20 15:00	Update Freshmeat, SourceForge, etc. 	Jonathan Fuerth 	Josh & Devrim	
9/20 19:00	9/20 15:00	Submit to Slashdot,Reddit,etc. 	Josh,Selena,Robert	 	
Category:PostgreSQL 9.0
91WebTasks

== Website Preparation ==
The following changes all need to be prepared so that they can go out in one commit at the appropriate time. Please put your name next to items which you can claim, and mark them when done.
* Home Page
** Call Box should say "9.1 Release" and have appropriate links -- Devrim
** Latest Releases should rotate to 9.1 and 8.2 should drop off -- Devrim
* News
**Write Internal announcement for News Item and Submit -- Josh, DONE sent to Devrim
**Check News Item
* Quotes
** Add 9.1 Quotes to quote rotation (5) -- Josh, DONE
** Approve quotes -- Devrim
*developers/beta:
**Needs to change to "Beta is over" page. -- Devrim DONE in staging
*about/press:
**Gather all presskits and translations -- Josh, DONE
**Need someone to review all of the new materials -- Josh, Devrim, REVIEWED ON STAGING SITE
***Correct presskits -- Josh DONE
**Create TOC for about/press -- Josh, DONE
*about
**Check Feature Matrix: Thom, DONE
*Documentation
**"9.1 beta" should change to "9.1" -- Devrim DONE in staging
**"What's New" link should point to 9.1 release notes -- Devrim DONE in staging
*External
**Submit Release to PRWire -- Josh, DONE
**Update Freshmeat -- Michael Brewer
**Update Wikipedia -- Thom, DONE
== Scheduled Deployments ==
Here's the things which need to be done, and the times they need to be done. Given issues in the past, we should have a responsible and a backup person for each task. The schedule below assumes a Sept. 12 release. Please add tasks as appropriate.
UTC Time 	EDT Time 	Task 	Person 	Backup 	Done?
9/9 04:00 	9/9 00:00 	Source Tarballs uploaded 	Tom 	 	Y
9/20 01:00	9/9 21:00 	Tarballs checkedFinal turnback point 	Packagers 	 	Y
9/10 01:00	9/9 21:00 	Go-ahead notice sent to RCsand to advance press 	Josh 	Bruce 	Y
9/10 18:00	9/10 14:00	All packages bundled and uploaded 	Packagers 	 	Y
9/10 21:00	9/10 17:00	Move FTP files to main FTP 	Devrim 	 	Y
9/12 11:00	9/12 07:00	Load new docs into website database 	Devrim 	 	Y
9/12 11:00	9/12 07:00	Merge changes into website, along with presskits.	Devrim 	 	Y
9/12 11:00	9/12 07:00	Approve news item and 9.1 quotes 	Devrim 	 	Y
9/12 11:00	9/12 07:00	Schedule website rebuild, inc. docs 	Devrim 	 	Y
9/12 13:30	9/12 09:30	Send out pgsql-announce 	Josh 	Bruce 	
9/12 13:30	9/12 09:30	Send out final notices to press 	Josh, RCs 	Bruce 	
9/12 19.00	9/12 15:00	Update Freshmeat, SourceForge, etc. 	??? 	Josh & Devrim	
9/12 19.00	9/12 15:00	Submit to Slashdot,Reddit,etc. 	Josh,Selena,Robert	 	
Category:PostgreSQL 9.1
9.1第49章

Chapter 46. 书写一个过程语言句柄
调用函数的时候，如果函数的书写语言不是目前的"版本 1"的编译语言接口（这包括用户定义的过程语言写的函数， 用 SQL 写的函数，以及用版本 0 的编译语言接口写的函数），都会通过一个 调用句柄处理具体的语言。 调用句柄有责任用一种有意义的方法执行这个函数，比如说解析所提供的文本等等。本章简介如何书写一个新的过程语言调用句柄。
过程语言的调用句柄是一个"普通"的函数， 必须使用一种编译语言来写，比如 C，使用版本-1的接口，并且在 PostgreSQL 里注册成接受零个参数并且返回类型 language_handler。 这个特殊的伪类型标识该函数为一个调用句柄并且避免它直接在 SQL 命令中被调用。
调用句柄的调用方式和其它函数一样：它接受一个指向一个 FunctionCallInfoData struct 的指针，这个指针包含参数值和有关被调用的函数的信息， 并且预期它返回一个 Datum 结果（如果它希望返回一个 SQL 的空结果， 那么可能设置 isnull 字段）。 调用句柄和普通的被调函数的区别是 FunctionCallInfoData 结构的 flinfo->fn_oid 字段强包含实际要调用的函数的 OID， 而不是调用句柄自身。调用句柄必须使用这个字段判断要执行哪个函数。 通常，传递进来的参数列表也是按照目标函数的声明设置的，而不是给调用句柄设置的。
从系统表 pg_proc 里抓取函数入口以及分析被调函数的参数和返回类型就是调用句柄的事了。 来自 CREATE FUNCTION 命令中的 AS 子句将会在 pg_proc 行的 prosrc 字段中找到。这个通常是过程语言本身的源文本，但也可以是别的东西，比如一个指向某个文件的路径名， 或者任何告诉调用句柄如何详细处理的东西。
通常，每个 SQL 语句里面可能要调用同一个函数多次。 调用句柄可以利用 flinfo->fn_extra 字段避免重复地查找有关被调函数地信息。 这个字段初始为 NULL，但是可以被调用句柄设置为指向有关被调函数的信息。 在随后的调用中，如果 flinfo->fn_extra 已经为非NULL，那么就可以直接使用它而免于重新查找信息。 调用句柄必须确保 flinfo->fn_extra 是用于指向一块至少会生存到当前查询结束的内存区里， 因为一个 FmgrInfo 数据结构将会保存那么长的时间。 一个实现这个要求的方法是在 flinfo->fn_mcxt 声明的内存环境里分配一块额外的数据； 这样的数据通常和 FmgrInfo 自己有一样的生命期。 但是句柄也可以同样选择使用一个更长生存期的环境，这样它就可以跨查询缓存函数定义。
在过程语言函数以触发器的形式调用的时候，就没有什么参数以通常的方式传递进来， 而是 FunctionCallInfoData 的 context 字段指向一个 TriggerData 结构， 而不是像普通函数调用里面的 NULL 那样。一个语言句柄应该为过程语言函数提供获取触发器信息的机制。
下面是一个用 C 写的存储过程语言句柄的模版：
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
PG_FUNCTION_INFO_V1(plsample_call_handler);
Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
 Datum retval;
 if (CALLED_AS_TRIGGER(fcinfo))
 {
 /*
 * 以触发器过程调用
 */
 TriggerData *trigdata = (TriggerData *) fcinfo->context;
 retval = ...
 }
 else
 {
 /*
 * 以函数调用
 */
 retval = ...
 }
 return retval;
}
在打点的地方放上几千行代码就可以完成调用句柄。
在把句柄函数编译成一个可装载的模块（参阅 Section 32.9.6）之后， 下面的命令就可以注册这个例子过程语言：
CREATE FUNCTION plsample_call_handler() RETURNS language_handler
 AS 'filename'
 LANGUAGE C;
CREATE LANGUAGE plsample
 HANDLER plsample_call_handler;
如果想书写自己的调用句柄，那么包含在标准发布里面的过程语言是很好的例子。 参考一下源代码树中的 src/pl 子目录。
Category:Chinese
9.1第52章

==52.1. 介绍==
GiST 的意思是通用的搜索树（Generalized Search Tree）。 它是一种平衡的，树状结构的访问方法，在系统中起一个基础的模版，然后可以 使用它实现任意索引模式。B+-trees，R-trees 和许多其它的索引模式都可以用 GiST 实现。
GiST 的一个优点是它允许一种客户化的数据类型和合适的 访问方法一起开发，并且是由该数据类型范畴里的专家，而不是数据库专家开发。
有些信息是从加州大学伯克力分校的 GiST 项目网站 和 Marcel Kornacker 的论文，Access Methods for Next-Generation Database Systems 中派生的。PostgreSQL 里的 GiST 实现目前主要是 Teodor Sigae 和 Oleg Bartunov 维护的， 在他们的网站上有更多信息。
==52.2. 扩展性==
通常，实现一种新的索引访问方法意味着大量的艰苦工作。我们必须理解数据库 的内部工作机制，比如锁的机制和预写日志。GiST 接口有 一个高层的抽象，只要求访问方法的实现者实现被访问的数据类型的语意。 GiST 层本身会处理并发，日志和搜索树结构的任务。
我们不要把这个扩展性和其它标准搜索树的扩展性混淆在一起，比如它们所能处理的 数据等方面。比如，PostgreSQL 支持可以扩展的 B+-trees 和 R-trees。这就意味着呢可以用 PostgreSQL 在任意你需要的数据类型上建立 B+-tree 或者 R-tree。但是 B+-trees 只支持范围谓词 （(<，=，>）， 而 R-trees 只支持 n-D （n－维）范围查询（包含，被包含，相等）。
所以，如果你用 PostgreSQL B+-tree 索引了一个图象 集，那么你就只能发出类似"图象 x 和 图象 y 相等吗"， "图象 x 是不是比图象 y 小" 和 "图象 x 是否大于图象 y"？这样的查询。 根据你在这个环境下定义的"等于"，"小于"，"大于" 的含义，上面这些查询可能有意义。但是，使用一个基于 GiST 的索引， 你可以创建一些方法来发出和域相关的问题，比如"找出所有马的图象" 或者"找出所有曝光过头的图象"。
要让一种 GiST 访问模式跑起来的方法只是实现七个用户定义 的方法，这七个方法定义了树里面的键字的行为。当然，为了支持那些怪异的查询，这些方法 也会相当怪异，但是对于所有标准的查询（B+-trees，R-trees 等），他们是相当直接的。 简单说，GiST 组合了扩展性和通用性，以及代码复用和一个干净的界面。 
==52.3. 实现==
一个用于 GiST 的索引操作符表必须提供的 七个方法：
*consistent给出一个在树的数据页上的谓词 p，和一个用户查询 q， 如果对于一个给定的数据项，p 和 q 都很明确地不能为真，那么这个方法将返回假。 
*union这个方法合并树中的信息。给出一个条目的集合，这个函数生成一个新的谓词， 这个谓词对所有这些条目都为真。 
*compress将数据项转换成一个适合于在一个索引页里面物理存储的格式。 
*decompresscompress 方法的反方法。把一个数据项的索引表现形式 转换成可以由数据库操作的格式。 
*penalty返回一个表示将新条目插入树中特定分支需要的"开销"的数值。 项将会按照树中最小 penalty 的路径插下去。 
*picksplit如果需要分裂一个页面的时候，这个函数决定页面中哪些条目保存呆旧页面里， 而哪些移动到新页面里。 
*same如果两个条目相同，返回真，否则返回假。
==49.4. 例子==
PostgreSQL 源代码版本包括好几个使用　GiST 实现的索引方法。核心系统目前为某些内置的几何数据类型提供 R-Tree 的等效功能 （参阅 src/backend/access/gist/gistproc.c）。 下面的 contrib 模块也包含 GiST 操作符表：
*btree_gist好几种类型的 B-Tree 等效
*cube用于多维立方体的索引
*intarray用于一维 int4 数组值的 RD-Tree
*ltree用于树状结构的索引
*pg_trgm使用 trigram 匹配的文本相似查找
*seg用于"漂浮范围（float range）"的索引
*tsearch2全文索引
==49.5. 崩溃恢复==
通常，重放 WAL 日志就足以再数据库崩溃之后恢复 GiST 索引的完整性。 不过，还存在一些边角的情况，这些时候索引状态无法完整地重建。 这时候索引从作用上仍然是正确的，但是可能会导致一些性能的降低。 在发生这种情况的时候，索引可以通过 VACUUM 其所有表来修复， 或者通过使用 REINDEX 重建索引来修复。在某些情况下，单纯的 VACUUM 是不够的，需要 VACUUM FULL 或者 REINDEX。 是否需要这些步骤，可以从崩溃恢复的日志信息中得到提示：
 LOG: index NNN/NNN/NNN needs VACUUM or REINDEX to finish crash recovery
或者在索引插入的时候出现下面的日志信息：
 LOG: index "FOO" needs VACUUM or REINDEX to finish crash recovery
如果一个单纯的 VACUUM 觉得自己无法完整地恢复，它会返回一个提示：
 NOTICE: index "FOO" needs VACUUM FULL or REINDEX to finish crash recovery
Category:Chinese
9.1第53章

52.1 介绍
GIN 表示通用倒排索引（Generalized Inverted Index）。它是一个索引结构，用来保存一个键值对（键字，张贴列表）的集合，在这里，一个“张贴列表”是一个存在有键值的行集合。每个索引的数值可以包含多个键字，因此某些行 ID 可以在很多张贴列表中出现。
通用的意思是，GIN 索引并不需要知道它为之加速的操作是什么。取而代之的是，它使用为特定数据类型定义的客户端策略。
GIN的一个有点是它允许客户数据类型的开发带着合适的访问方法，而且是由这个数据类型领域的专家实现，而不是一个数据库专家来实现。这个优点和 GiST 非常类似。
PostgreSQL 里面的 GIN 实现是 Teodor Sigaev 和 Oleg Bartunov 维护的。在它们的网站上有更多GIN相关的信息。 
52.2 扩展性
GIN 接口有一个高层次的抽象，只需要访问方法实现者实现被访问的数据类型的语意。GIN 层本身负责处理并发性，日志和搜索树结构。
要让一个 GIN 访问方法可以运行，我们只需要实现四个用户定义的方法，这四个方法定义树里面的键字的行为和键字，索引值和可索引的查询之间的关系。简单说 GIN 把通用性，代码重用性和干净的界面组合在了一起。
GIN 的索引操作符表必须提供的四个方法是：
int compare(Datum a, Datum b)
 比较键字（不是索引后的数值！），返回一个小于零，等于零或者大于零的整数，表示第一个键字是否小于，等于或者大于第二个键字。 
Datum* extractValue(Datum inputValue, int32 *nkeys)
 给出一个要索引的值，返回一个键字的数组。返回的键字的个数必须存储在 *nkeys 里头。 
Datum* extractQuery(Datum query, int32 *nkeys, StrategyNumber n)
 给出一个带查询的数值，返回一个键字的数组；也就是说，查询是在一个可以索引的操作符右手边的关系，而这个操作符左手边是索引的字段。 n 是操作符在操作符表里面的策略号（见第34.14.2小节）。通常，extractQuery 需要用 n 来判断查询的数据类型和需要抽取的键值。返回的键字的个数必须存储在 *nkeys 里头。如果键字的个数等于零，那么 extractQuery 应该在 *nkeys 里头存储 0或者 -1。0 意味着任何匹配查询的行都会产生一个顺序扫描。 -1 意味着没有什么东西可以满足查询。数值的选择应该基于带有给出策略号的操作的语意进行。 
bool consistent(bool check[], StrategyNumber n, Datum query)
 如果索引的数值满足（或者如果操作符在操作符表里面标记为 RECHECK，那么就是“会满足”）策略号为 n 的查询操作符，则返回真。 check 数组长度和前面用于这个查询的 extractQuery 返回的键字的个数相同。如果索引过的数值暴汉对应的查询键字，那么 check 对应的元素就是 TRUE，也就是说，如果 (check[i] == TRUE)，那么 extractQuery 结果数组的第 i 个键字就出现在索引过的数值中。最初的查询数据（不是抽取出来的键字数组！）会传递进来，以便 consistent 方法需要使用之。
Category:Chinese
9.1第55章

后端接口（BKI）文件是一些用特殊语言写的脚本，这些脚本是 PostgreSQL 后端能够理解的，以特殊的 "bootstrap"（引导）模式运行，这种模式允许在不存在系统表的零初始条件下执行数据库函数，而普通的 SQL 命令要求系统表必须存在。因此 BKI 文件可以用于在第一时间创建数据库系统。（可能除此以外也没有其它用处。）
在创建一个新的数据库集群的时候， initdb就是使用 BKI 文件来完成其工作的一部分。 initdb使用的输入的文件是作为制作 PostgreSQL的一部分，由一个叫 genbki.sh 的程序创建的，这个程序读取源代码树目录的 src/include/catalog/ 目录里面的几个特殊格式的 C 头文件。生成的 BKI文件叫 postgres.bki 并且通常安装在安装树里的 share 子目录。
相关的信息可以在有关 initdb 的文档中找到。
==55.1. BKI 文件格式==
本节描述 PostgreSQL 后端是如何理解 BKI 文件。如果把 postgres.bki 文件拿来做为例子， 这些描述会变得容易理解些。 你还可以学习 initdb 的源程序以便获取后端是如何激活的概念。
BKI输入是由一系列命令组成的。 命令是由一些记号组成的，具体是什么由命令语法决定。记号通常是用空白分隔的，但是如果没有歧义的话可以不要。 没有什么特殊的命令分隔符；语法上无法属于前面命令的记号开始新的一条命令。 （通常你会把一条新的命令放在新的一行上以保持清晰。） 记号可以是某些关键字，特殊字符（圆括弧，逗号等），数字，或者双引号字串。 所有东西都是大小写敏感的。
以 # 开头的行被忽略。 
==55.2. BKI命令==
*create [bootstrap] [shared_relation] [without_oids] tablename tableoid (name1 = type1 [, name2 = type2, ...])
创建一个叫做 tablename，OID 为 tableoid 的表，表字段在圆括弧中给出。
bootstrap.c 直接支持下列字段类型： bool，bytea，char （1 字节）， name，int2，int4， regproc，regclass， regtype，text，oid， tid，xid， cid，int2vector，oidvector， _int4 （数组），_text （数组）， _aclitem（数组）。尽管我们可以创建包含其它类型字段的表， 但是我们只有在创建完 pg_type 并且填充了合适的记录之后才行。 （这实际上就意味着在系统初始化表中，只能使用这些字段类型，而非系统初始化表可以使用任意内置类型。）
如果声明了 bootstrap，那么改表将只在磁盘上创建； 不会向 pg_class，pg_attribute 等系统表里面输入任何东西。 因此这样的表将无法被普通的 SQL 操作访问，直到那些记录用硬办法（用 insert 命令）填入。 这个选项用于创建 pg_class 等自身。
如果声明了 shared_relation，那么表就作为共享表创建。 除非声明了 without_oids，否则将会有 OID。 
*open tablename打开一个名为 tablename 的表，准备插入数据。任何当前已经打开的表都会被关闭。 
*close [tablename]关闭打开的表。给出的表明是用于交叉检查，但并不是必须的。 
*insert [OID = oid_value] (value1 value2 ...)用 value1， value2， 等作为字段值以及 oid_value 作为其 OID（对象标识）向打开的表插入一条新记录，如果 oid_value 为零（0），否则省略了改子句，而表则拥有 OID，并赋予下一个可用的 OID 数值。NULL 可以用特殊的关键字 _null_声明。包含空白的值必须用双引号栝起。 
declare [unique] index indexname indexoid on tablename using amname ( opclass1 name1 [, ...] )
 在一个叫 tablename 的表上用 amname 访问方法创建一个 OID 是 indexoid 的叫做 indexname 的索引。 索引的字段叫 name1，name2 等，而使用的操作符表分别是 opclass1，opclass2 等。 将会创建索引文件和恰当的系统表记录，但是索引内容不会被此命令初始化。 
*build indices填充前面声明的索引。 
==55.3. 系统初始化的 BKI 文件的结构==
open 命令打开的表需要系统事先存在另外一些基本的表， 在这些表存在并拥有数据之前，我们不能使用 open 命令。 （这些最低限度必须存在的表是 pg_class，pg_attribute， pg_proc，和 pg_type。） 为了允许这些表自己被填充，带着 bootstrap 选项的 create 隐含打开所创建的表用于插入数据。
因此，postgres.bki 文件的结构必须是这样的：
 1.create bootstrap 其中一个关键表
 2.insert 数据，这些数据至少描述这些关键表本身
 3.close
 4.重复创建和填充其它关键表。
 5.create （不带 bootstrap）一个非关键表
 6.open
 7.insert 需要的数据
 8.close
 9.重复创建其它非关键表。
 10.定义索引。
 11.build indices 
当然，肯定还有其它未记录文档的顺序依赖关系。 
==55.4. 例子==
下面的命令集将创建名为 test_table，有两个字段 cola 和 colb，类型分别为 int4 和 text 的表，表的 OID 为 420， 然后向该表插入两行。
 create test_table 420 (cola = int4, colb = text)
 open test_table
 insert OID=421 ( 1 "value1" )
 insert OID=422 ( 2 _null_ )
 close test_table
Category:Chinese
9.1第三十七章

==第37章. 规则系统（The Rule System）==
本章讨论PostgreSQL的规则系统（rule system）。产生式规则系统（production rule system）的概念很简单，但是在实际使用它们的时候会遇到很多微妙的问题。
其它很多数据库系统定义了主动数据库规则（active database rule），这些规则通常是一些存储过程（stored procedure）以及触发器（trigger）。在PostgreSQL中，同样可以使用函数（function）和触发器来实现它们。
但是，规则系统（更准确的说，查询重写规则系统query rewrite rule system）是和存储过程以及触发器完全不同的东西。它考虑规则并修改查询语句，然后将修改后的查询传递给查询计划器（query planner）来生成查询计划并且执行。PostgreSQL的规则系统非常的强大，可以用在很多地方，比如说查询语言过程（procedure），视图（view），版本（version）等。规则系统的理论基础和强大之处在以下两篇文章中有介绍：[On Rules, Procedures, Caching and Views in Database Systems] 和[A Unified Framework for Version Modeling Using Production Rules in a Database System]。
===37.1. 查询树（Query Tree）===
要理解规则系统如何工作，我们需要知道它什么时候会被触发，以及它的输入和输出的结果分别是什么。
规则系统位于语法分析器（parser）和查询计划器（planner）之间。规则系统的输入是分析器的输出和用户定义的重写规则，而它的输出结果是它以此创建的查询树（零个或多个）。其中分析器的输出是一棵查询树，用户自定义的重写规则也是查询树，只不过多了一些额外的信息。因此，规则系统的输入和输出仍然是分析器自己可以产生的东西，也就是说，查询树。因而，任何规则系统可以看到的东西在本质上都可以用SQL语句来表示。
那么，什么是查询树（query tree）呢？它是SQL语句的内部表示，它把SQL语句的每一部分都单独存储。如果你设置了服务器的这几个参数（debug_print_parse, debug_print_rewritten, debug_print_plan），你可以在服务器日志中看到这些查询树。规则动作（action）也以查询树的形式存储在系统表pg_rewrite中。虽然它们不是日志输出那样的格式，但是它们包含的信息是完全一样的。
需要有相关的经验才能读懂查询树。但是，因为读懂了查询树所代表的SQL语句就能理解规则系统，所以本章并不介绍如何读懂查询树。
在本章中，当阅读查询树的SQL表示时，需要能够识别出语句中和查询树结构的各部分相对应的部分。一棵查询树包含下面几部分：
Category:Chinese
9.1第三十八章

== 第三十八章 过程语言 ==
PostgreSQL允许用户定义的函数使用SQL和C之外的语言编写。通常这些额外的语言叫做过程语言（PLs）。如果我们用一种过程语言书写了一个函数，那么数据库服务器是没有任何内建的知识获知如何解析该函数的源文本的。实际上这些任务都传递给一个知道如何处理这些细节的句柄处理。 这个句柄既可以自己干所有的分析，语法分析，执行等的工作，也可以充当PostgreSQL和一种现有的编程语言实现之间的"胶水"。句柄本身是一C语言函数，它被编译成一种共享对象并且在需要的时候装载，就像其它C函数一样。
目前在标准的 PostgreSQL 发布里有四种过程语言可用：PL/pgSQL（Chapter 39），PL/Tcl（Chapter 40），PL/Perl（Chapter 41）和PL、Python（Chapter 42）。还有几种额外的过程语言没有包含在核心发布里。AppendixG中有关于他们的信息。用户可以定义其它语言。开发一种新的过程语言的基本信息在 Chapter 49 里介绍。
== 38.1. 安装过程语言 ==
如果你要试用某种过程语言，你必须要将它安装在数据库中。不过那些安装到数据库 template1 里的过程语言会自动在随后创建的数据库中安装，因为他们在template1中的条目将会被CREATE DATABASE命令复制。所有，数据管理员可以决定用哪种语言，以及缺省时用哪个语言。
对于那些随着标准版本发布的语言，只需要用CREATE EXTENSION language_name在当前数据库中进行安装。或者可以用程序createlang在shell命令行进行安装。例如，在数据库template1中安装PL/Perl语言，使用：
 createlang plperl template1
下面描述的手工安装的方法只是适用于那些createlang还不知道的语言。 
手动安装过程语言
在数据库中安装过程语言有五个步骤，首先必须是数据库的超级用户。在大多数情况下，所需的SQL命令应该被打包为一个“扩展”的安装脚本，以便用CREATE EXTENSION命令执行它。
1.语言句柄的共享对象必须被编译并且安装在一个合适的库目录。这个工作使用的方法跟创建和安装一个用户自定义的C函数是一样的；见Section 35.9.6。通常，一个语言的句柄依赖与一个外部的库来提供实际的程序语言引擎；如果是这样，那么那些库也需要安装.
2.句柄必须用命令进行声明
 CREATE FUNCTION handler_function_name()
 RETURNS language_handler
 AS 'path-to-shared-object'
 LANGUAGE C;
这个特殊的language_handler返回类型是告诉数据库系统这个函数不返回已定义的SQL数据类型，不能直接在SQL语句中使用。
3.这个语言句柄能提供一个“排队法（inline）”处理函数，在这个编写的语言中匿名的执行代码块（DO命令）。如果这个语言提供一个内嵌的处理函数，那么可以用下面的命令来进行声明：
 CREATE FUNCTION inline_function_name(internal)
 RETURNS void
 AS 'path-to-shared-object'
 LANGUAGE C;
4.语言句柄可以提供一个"验证器"函数，这个函数检查函数定义是否正确， 而不会实际执行它。如果这个验证器函数存在，那么可以用CREATE FUNCTION进行调用。如果这个验证器函数由句柄调用，那么可以用下面的命令来声明它：
 CREATE FUNCTION validator_function_name(oid)
 RETURNS void
 AS 'path-to-shared-object'
 LANGUAGE C STRICT;一个验证器函数由句柄提供，那么用下面的命令声明 
5.最后，PL必须 用下面的命令进行声明：
 CREATE [TRUSTED] [PROCEDURAL] LANGUAGE language-name
 HANDLER handler_function_name
 [INLINE inline_function_name]
 [VALIDATOR validator_function_name] ;
这个可选的关键字TRUSTED声明用户是否有权限来访问这个数据。TRUSTED用于为普通的数据库用户（没有超级用户权限）有权限使用这种语言创建函数和触发器过程。由于PL函数是在数据库内部执行，所以这个TRUSTED标志只用于那些不允许访问数据库内部或者文件系统的语言。语言PL/pgSQL，PL/Tcl和PL/Perl都被认为是可信的，语言PL/TclU，PL/PerlU和PL/PythonU被设计成提供无限制的功能，因此不应该标志成可信的。
Example 38-1 显示如何手工安装PL/Perl过程语言。
 Example 38-1. 手工安装 PL/Perl
下面的命令告诉数据库到那里才能找到用于 PL/pgSQL语言的调用句柄函数的共享对象：
 CREATE FUNCTION plperl_call_handler() RETURNS language_handler AS
 '$libdir/plperl' LANGUAGE C;
 PL/Perl 有一个排队法处理函数和一个验证器函数, 所以我们也要声明它:
 CREATE FUNCTION plperl_inline_handler(internal) RETURNS void AS
 '$libdir/plperl' LANGUAGE C;
 CREATE FUNCTION plperl_validator(oid) RETURNS void AS
 '$libdir/plperl' LANGUAGE C STRICT;
这个命令:
 CREATE TRUSTED PROCEDURAL LANGUAGE plperl
 HANDLER plperl_call_handler
 INLINE plperl_inline_handler
 VALIDATOR plperl_validator;
声明了前面所定义的函数应该为那些调用语言属性是 plperl 的函数和触发器过程被调用的时候使用。 
在PostgreSQL默认安装里，这个PL/pgSQL语言的句柄创建和安装在“library”目录中，此外，这个PL/pgSQL语言本身将安装在所有数据库中。如果Tcl被配置支持，PL/Tcl和PL/TclU句柄将创建和安装在library目录中，但是这个语言本身默认不会安装在任意一个数据库中。同样的，如果Perl被配置成支持，那么这个PL/Perl和PL/PerlU句柄也将被创建和安装，并且如果Python被配置成支持，PL/PythonU句柄也将会被安装，但是这个语言默认将不会被安装。
Category:Chinese
9.1第二十八章

==Chapter 28. 监控磁盘的使用==
本章讨论如何监控PostgreSQL数据库系统的磁盘使用情况。
===28.1. 判断磁盘的使用量===
每个表都有一个主堆磁盘文件，大多数数据都存储在这里。如果一个表有着可能会很长的字段，则另外还有一个 TOAST 文件与这个表相关联，用于存储因为数值太长而不能存储在主表里面的数据（请参考 54.2 节）。如果有这个扩展表，那么表上会有一个TOAST索引。当然，同时还可能有索引和基础表关联。每个表和索引都存放在单独的磁盘文件里 —— 如果文件超过一G字节，甚至可能多于一个文件。这些文件的命名规则在 50.1 小节里描述。
你有三种监控磁盘空间的方法：使用表 9-58 列出的 SQL 函数，使用 contrib/oid2name 里面的工具，或者手工观察系统 catalogs。SQL 函数最容易使用，是推荐的方法。contrib/oid2name 在 F.19 小节里讨论。本小节剩下的部分显示如何通过观察系统 catalogs 实现这些功能。
如果使用 psql 连接到任何最近刚刚清理或者分析过的数据库， 那么我们可以用查询来查看任意表的磁盘使用： 
 SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
 pg_relation_filepath | relpages 
 ----------------------+----------
 base/16384/16806 | 60
 (1 row)
每个页通常为 8K 字节。（请记住，relpages 只能通过 VACUUM，ANALYZE 和一些例如 CREATE INDEX 一类的 DLL 命令更新。）如果你想直接检查表的磁盘文件，那么给出的文件名应该有用。
想显示 TOAST 表使用的空间，使用如下的查询：
 SELECT relname, relpages
 FROM pg_class,
 (SELECT reltoastrelid
 FROM pg_class
 WHERE relname = 'customer') AS ss
 WHERE oid = ss.reltoastrelid OR
 oid = (SELECT reltoastidxid
 FROM pg_class
 WHERE oid = ss.reltoastrelid)
 ORDER BY relname;
 
 relname | relpages 
 ----------------------+----------
 pg_toast_16806 | 0
 pg_toast_16806_index | 1
你也可以很容易地显示索引的大小：
 SELECT c2.relname, c2.relpages
 FROM pg_class c, pg_class c2, pg_index i
 WHERE c.relname = 'customer' AND
 c.oid = i.indrelid AND
 c2.oid = i.indexrelid
 ORDER BY c2.relname;
 
 relname | relpages 
 ----------------------+----------
 customer_id_indexdex | 26
使用以下信息可以很容易找到你的最大的表和索引：
 SELECT relname, relpages
 FROM pg_class
 ORDER BY relpages DESC;
 relname | relpages 
 ----------------------+----------
 bigtable | 3290
 customer | 3144
===28.2. 磁盘满导致的失效===
数据库管理员最重要的磁盘监控任务是确保磁盘不要被撑满。被撑满的数据磁盘不会导致数据破坏，但它肯定会导致系统进一步使用的问题。如果保存 WAL 文件的磁盘被撑满了，数据库服务器可能停止服务然后接下来可能关闭。
如果你无法通过删除其他东西释放更多的空间，你可以通过使用表空间来移动一些数据库文件到其他的文件系统。更多信息请参考 21.6 小节。
 提示：一些文件系统在它接近满的时候的性能极低，所以请不要在磁盘完全满了的时候才采取行动。
如果你的系统支持针对每用户的磁盘配额，那么数据库将自然受制于用户所处的服务器给他的份额限制。超过份额的负面影响和用光磁盘是完全一样的。
Category:Chinese
9.1第六章

==数据处理(Data Manipulation)==
===插入数据(Inserting Data) ===
在创建完一个表的时候，它里面没有数据。在数据库使用前要做的第一件事就是向里面插入数据。数据在概念上是每次插入一行。当然可以每次插入多行，但是每次插入都不能小于一行的数据。即使你只知道几个字段的数值，数据库也将创建一个完整的新行。
使用 INSERT 命令创建一个新行。这条命令要求提供表名字以及表中每个字段的值。比如，假设来Chapter 5的产品表：
CREATE TABLE products (
 product_no integer,
 name text,
 price numeric
);
下面例子是向一个表中插入一行：
INSERT INTO products VALUES (1, 'Cheese', 9.99);
数据值是按照这些字段在表中出现的顺序列出的，并且用逗号分隔。通常，数据值是文本(常量)，但也允许使用标量表达式。
上述语法的缺点是你必须知道表中字段的顺序。你也可以明确地列出字段以避免这个问题。比如，下面的两条命令都和上面的那条命令效果相同：
INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99);
INSERT INTO products (name, price, product_no) VALUES ('Cheese', 9.99, 1);
许多用户认为明确列出字段名是个好习惯。
如果你不知道所有字段的数值，那么可以省略其中的一些。这时候，这些未知字段将被填充为它们已经设置好的的缺省值。比如：
INSERT INTO products (product_no, name) VALUES (1, 'Cheese');
INSERT INTO products VALUES (1, 'Cheese');
第二种形式是 PostgreSQL 的一个扩展。它从左向右填充字段，先使用一些指定的值，而剩余的填充缺省值。
为了更为清晰，你也可以对独立的字段或者整个行明确使用缺省值：
INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT);
INSERT INTO products DEFAULT VALUES;
你可以在一条命令中插入多行：
INSERT INTO products (product_no, name, price) VALUES
 (1, 'Cheese', 9.99),
 (2, 'Bread', 1.99),
 (3, 'Milk', 2.99);
【提示】要一次插入大量数据，可以看看 COPY 命令。它不像 INSERT 命令那么灵活，但是更高效。参考节14.4获取更多有关提高装载海量数据的性能。
=== 更新数据(Updating Data)===
修改已经存储在数据库中的数据的行为叫做更新。你可以更新单独的一行，也可以更新表中所有的行，还可以更新其中的一部分行。可以独立地更新每个字段，而其它的字段则不受影响。
要存在的行执行更新，你需要三种信息：
1 表的名字和表里要更新的字段名
2 字段的新值
3 要更新哪些行
我们在章5里说过，SQL 通常并不为数据行提供唯一标识。因此我们无法直接指定需要更新哪一行。但是，我们可以通过指定一个被更新的行需要满足的条件。只有在表里存在主键的时候 (不管你叫它什么)，我们才能通过条件选取主键，有效的指定一个独立的行。图形化的数据库访问工具可以充许你更新独立行
比如，这条命令将所有产品价格为5的重新定价为10 ：
UPDATE products SET price = 10 WHERE price = 5;
这样做可能导致零行、一行或多行数据被更新。如果我们试图执行一个不匹配任何行的更新，那也正确的。
让我们仔细看看这个命令。首先是关键字 UPDATE 跟着表名字。和平常一样，表名字也可以是用模式修饰的，否则就会从模式路径中把它找出来。然后是关键字 SET 跟着字段名与一个等号以及新的字段值。新的字段值可以是任意标量表达式，而不仅仅是常量。比如，如果你想把所有产品的价格提高 10% ，可以用：
UPDATE products SET price = price * 1.10;
如你所见，新值的表达式也可以引用行中现有的数值。我们还忽略了 WHERE 子句。如果我们忽略了这个子句，那么表中所有的行都要被更新。如果出现了 WHERE 子句，那么只有匹配其条件的行才会被更新。请注意在 SET 子句中的等号是一个赋值，而在 WHERE 子句中的等号是比较，不过这样并不会导致任何歧义。当然 WHERE 条件不一定非得是相等测试。许多其它操作符也都可以使用(参阅章9)。但是表达式必须得出一个布尔结果。
你还可以在一个 UPDATE 命令中更新更多的字段，方法是在 SET 子句中列出更多分配值。比如：
UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a > 0;
=== 删除数据(Deleting Data)===
到目前为止我们已经解释了如何向表中增加数据以及如何改变数据。剩下的是讨论如何删除不再需要的数据。和前面增加数据一样，删除数据也必须是从表中整行整行地删除。在上一节里我们提到了 SQL没有提供直接访问独立行的方法。因此，删除行只能是通过指定被删除行的匹配条件进行。如果你在表上有一个主键，那么你可以指定准确的行。当然，你也可以删除匹配条件的一组行，或者一次删除表中的所有行。
我们使用 DELETE 命令删除行。它的语法和 UPDATE 命令非常类似。比如，要从产品表中删除所有价格为 10 的产品的行，可以这样
DELETE FROM products WHERE price = 10;
如果你只是写
DELETE FROM products;
那么表中所有行都会被删除！程序员一定要注意。
Category:Chinese
9.1第四十二章

PL/Python这门过程语言让你你可以用Python语言写PostgreSQL函数.
要在具体的数据库里安装PL/Python,使用CREATE EXTENSION plpythonu指令,或者在Shell命令行环境下用createlang plpythonu dbname命令
:提示:：如果一个语言被安装到数据库模板Template1里面,那么所有后续创建的数据库都自动安装了这门语言
在PosgreSQL7.4版本里面，PL/Python仅仅被当作一门不可信任的语言而使用，也就意味着:他不提供任何方法来限制用户用它能做什么.因为它被另外命名为plpython。如果在Python中能开发一个安全的执行机制,可信任变体plpython将来可能能再次可用。使用不可信任的PL/Python写函数的开发者要注意：你的函数不能用来做任何意图外的多余之事。因为这些函数可以用来做任何数据库管理员角色权限可做的事情.只有超级用户可以写函数时用不可信任的语言，比如pypython.
:注意:使用源码包的用户，在PL/Python的安装过程中必须明确启用其编译构建过程.(更多信息请参考安装说明章节。)二进制包的使用者可以在一个单独的子包中找到PL/Python.
==42.1、Python 2 VS Python 3==
PL/Python同时支持Python2和Python3两种语言变体。（PostgreSQL安装说明部分可能包含更精确的最小Python支持版本集的详细信息。）因为Python2和Python3两种语言的变体在一些重要方面是不兼容的,PL/Python使用下面的命名和转换模型来避免两种语言的混合。
* 用plpython2u命名的PostgreSQL语言实现基于Python2语言变体的PL/Python。
* 用plpython3u命名的PostgreSQL语言实现基于Python3语言变体的PL/Python。
* 用plpythonu命名的语言实现基于默认Python版本语言变体的PL/Python。目前的默认版本是Python2。（这个PostgreSQL数据库环境内的默认版本和你操作系统环境内安装的Python默认版本没有任何关系,比如Linux系统上默认安装版本可能是/usr/bin/python.）在PostgreSQL遥远来来的某个发行版本中，数据库环境内的默认Python版本可能会变为Python3,这个问题实际取决于Python语言社区本身在向Python3版本迁移方面的工作进展.