PostgreSQL 消息格式
本节描述各种消息的详细格式。每种消息都标记来指示它是由前端(F)、后端(B)或者两者(F & B)发送的。 请注意,尽管每条消息在开头都包含一个字节计数,但是消息格式也被定义为无需参考字节计数就可以找到消息的结尾。 这样是为了有效性检查(CopyData消息是一个例外,因为它形成一个数据流的一部分;任意独立的CopyData消息可能是无法自解释的)。
- AuthenticationOk (B)
-
- Byte1('R')
-
标识该消息是一条认证请求。
- Int32(8)
-
以字节计的消息内容长度,包括这个长度本身。
- Int32(0)
-
指定该认证是成功的。
- AuthenticationKerberosV5 (B)
-
- Byte1('R')
-
标识该消息是一条认证请求。
- Int32(8)
-
以字节计的消息内容长度,包括长度自身。
- Int32(2)
-
指定要求Kerberos V5认证。
- AuthenticationCleartextPassword (B)
-
- Byte1('R')
-
标识该消息是一条认证请求。
- Int32(8)
-
以字节计的消息内容长度,包括长度自身。
- Int32(3)
-
指定要求一个明文的口令。
- AuthenticationMD5Password (B)
-
- Byte1('R')
-
标识这条消息是一个认证请求。
- Int32(12)
-
以字节计的消息内容的长度,包括长度本身。
- Int32(5)
-
指定要求一个MD5加密的口令。
- Byte4
-
加密口令的时候使用的盐粒。
- AuthenticationSCMCredential (B)
-
- Byte1('R')
-
标识这条消息是一个认证请求。
- Int32(8)
-
以字节计的消息内容长度,包括长度本身。
- Int32(6)
-
指定请求一个SCM信任消息。
- AuthenticationGSS (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32(8)
-
消息内容的长度以字节为单位,包括自己。
- Int32(7)
-
指定被请求的是GSSAPI认证。
- AuthenticationSSPI (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32(8)
-
消息内容的长度以字节为单位,包括自己。
- Int32(9)
-
指定被请求的是SSPI认证。
- AuthenticationGSSContinue (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32
-
消息内容的长度以字节为单位,包括自己。
- Int32(8)
-
指定该消息包含GSSAPI或SSPI数据。
-
Byte
n -
GSSAPI或SSPI认证数据。
- AuthenticationSASL (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
- Int32(10)
-
指定SASL认证被要求。
消息体是一个SASL认证机制的列表,该列表按照服务器偏爱的顺序组织。在最后一个认证机制名称的后面需要一个零字节作为终结符。对于每一种机制,有下列信息:
- String
-
一种SASL认证机制的名称。
- AuthenticationSASLContinue (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
- Int32(11)
-
指定这个消息包含一个SASL挑战。
-
Byte
n -
SASL数据,与使用的SASL机制有关。
- AuthenticationSASLFinal (B)
-
- Byte1('R')
-
标识该消息是一个认证请求。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
- Int32(12)
-
指定SASL认证已经完成。
-
Byte
n -
SASL产出的“额外数据”,与使用的SASL机制有关。
- BackendKeyData (B)
-
- Byte1('K')
-
标识该消息是一个取消键数据。如果前端希望能够在稍后发出CancelRequest消息, 那么它必须保存这个值。
- Int32(12)
-
以字节计的消息内容的长度,包括长度本身。
- Int32
-
后端的进程号(PID)。
- Int32
-
此后端的密钥。
- Bind (F)
-
- Byte1('B')
-
标识该信息是一个绑定命令。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
- String
-
目标入口的名字(空字符串则选取未命名的入口)。
- String
-
源预备语句的名字(空字符串则选取未命名的预备语句)。
- Int16
-
后面跟着的参数格式代码的数目(由下文的
C说明)。 这个数值可以是零,表示没有参数,或者是参数都使用缺省格式(文本); 也可以是一,这种情况下指定的格式代码被应用于所有参数;或者它可以等于实际参数的数目。 -
Int16[
C] -
参数格式代码。目前每个都必须是零(文本)或者一(二进制)。
- Int16
-
后面跟着的参数值的数目(可能为零)。这些必须和查询需要的参数个数匹配。
然后,每个参数都会出现下面的域对:
- Int32
-
参数值的长度,以字节计(这个长度并不包含长度本身)。可以为零。 一个特殊的情况是,-1 表示一个NULL参数值。在NULL 的情况下, 后面不会跟着字节值。
-
Byte
n -
参数值,使用关联的格式代码表示的格式。
n是上文的长度。
在最后一个参数之后,出现下面的域:
- Int16
-
后面跟着的结果列格式代码数目(下文的
R描述)。 这个数目可以是零表示没有结果列或者结果列都使用缺省格式(文本); 也可以是一,这种情况下指定的格式代码被应用于所有结果列(如果有的话);或者它可以等于查询的结果列的实际数目。 -
Int16[
R] -
结果列格式代码。目前每个必须是零(文本)或者一(二进制)。
- BindComplete (B)
-
- Byte1('2')
-
标识该消息为一个绑定结束标识符。
- Int32(4)
-
以字节计的消息长度,包括长度本身。
- CancelRequest (F)
-
- Int32(16)
-
以字节计的消息长度。包括长度本身。
- Int32(80877102)
-
取消请求代码。该值被选中在高16位包含
1234,并且在低16位包含5678(为避免混淆,这个代码不能和任何协议版本号相同)。 - Int32
-
目标后端的进程号(PID)。
- Int32
-
目标后端的密钥。
- Close (F)
-
- Byte1('C')
-
标识这条消息是一个Close命令。
- Int32
-
以字节计的消息内容长度,包括长度本身。
- Byte1
-
'
S'关闭一个准备的语句;或者'P'关闭一个入口。 - String
-
一个要关闭的预备语句或者入口的名字(一个空字符串选择未命名的预备语句或者入口)。
- CloseComplete (B)
-
- Byte1('3')
-
标识消息是一个Close完成指示器。
- Int32(4)
-
以字节计的消息内容的长度,包括长度本身。
- CommandComplete (B)
-
- Byte1('C')
-
标识此消息是一个命令结束响应。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
- String
-
命令标记。它通常是一个单字,标识被完成的SQL命令。
对于
INSERT命令,该标记是INSERT, 其中oidrowsrows是已被插入的行数。如果rows为1并且目标表已有OIDs,oid为已插入行的对象ID;但是OIDs 系统列已经不再被支持;因此oid始终为 0。对于
DELETE命令,该标记是DELETE, 其中rowsrows是已被删除的行数。对于
UPDATE命令,该标记是UPDATE,其中rowsrows是已被更新的行数。对于
SELECT或CREATE TABLE AS命令,该标记是SELECT,其中rowsrows是被检索的行数。对于
MOVE命令,该标记是MOVE,其中rowsrows是游标位置被移动的行数。对于
FETCH命令,该标记是FETCH,其中rowsrows是已从游标中检索出来的行数。对于
COPY命令,该标记是COPY,其中rowsrows是已拷贝的行数(注意,行计数只在PostgreSQL 8.2及其后的版本中出现)。
- CopyData (F & B)
-
- Byte1('d')
-
标识这条消息是一个
COPY数据。 - Int32
-
以字节计的消息内容的长度,包括长度本身。
-
Byte
n -
构成
COPY数据流的一部分的数据。从后端发出的消息总是对应单一的数据行,但是前端发出的消息可能会任意分割数据流。
- CopyDone (F & B)
-
- Byte1('c')
-
标识这条信息是一个
COPY结束指示器。 - Int32(4)
-
以字节计的消息内容长度,包括长度本身。
- CopyFail (F)
-
- Byte1('f')
-
标识这条消息是一个
COPY失败指示器。 - Int32
-
以字节计的消息内容的长度,包括长度本身。
- String
-
一个报告失败原因的错误消息。
- CopyInResponse (B)
-
- Byte1('G')
-
标识这条消息是一条Start Copy In(开始拷贝入)响应消息。前端现在必须发送拷贝入数据(如果还没准备好做这些事情,那么发送一条CopyFail消息)。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
- Int8
-
0表示全体拷贝格式都是文本(数据行由新符分隔, 列由分隔字符分隔等等)。1 表示全体拷贝格式都是二进制的(类似于DataRow 格式)。参阅COPY获取更多信息。
- Int16
-
要拷贝的数据中的列数(由下文的
N解释)。 -
Int16[
N] -
每个列要使用的格式代码。目前每个都必须是零(文本)或者一(二进制)。 如果全体拷贝格式都是文本,那么所有的都必须是零。
- CopyOutResponse (B)
-
- Byte1('H')
-
标识这条消息是一条Start Copy Out(开始拷贝出)响应消息。这条消息后面将跟着拷贝出数据。
- Int32
-
以字节计的消息内容的长度,包括它自己。
- Int8
-
0表示全体拷贝格式都是文本(数据行由新符分隔, 列由分隔字符分隔等等)。1 表示全体拷贝格式都是二进制的(类似于DataRow 格式)。参阅COPY获取更多信息。
- Int16
-
要拷贝的数据的列数(在下文的
N说明)。 -
Int16[
N] -
每个列要使用的格式代码。目前每个都必须是零(文本)或者一(二进制)。 如果全体拷贝格式都是文本,那么所有的都必须是零。
- CopyBothResponse (B)
-
- Byte1('W')
-
标识这个消息是一个Start Copy Both(启动双向复制)响应。这个消息只用于流复制。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- Int8
-
0表示全体
COPY格式都是文本(数据行由新符分隔,列由分隔字符分隔等等)。1 表示全体拷贝格式都是二进制的(类似于DataRow格式)。参阅COPY获取更多信息。 - Int16
-
要拷贝的数据中的列数目(在下文的
N说明)。 -
Int16[
N] -
每个列要使用的格式代码。目前每个都必须是零(文本)或者一(二进制)。 如果全体拷贝格式都是文本,那么所有的代码都必须是零。
- DataRow (B)
-
- Byte1('D')
-
标识这个消息是一个数据行。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- Int16
-
后面跟着的列值的个数(可能是零)。
然后,为每个列都会出现下面的域对:
- Int32
-
列值的长度,以字节计(这个长度不包括它自己)。可以为零。一个特殊的情况是,-1表示一个NULL的域值。 如果是NULL的情况则后面不会跟着值字节。
-
Byte
n -
一个列的数值,以相关的格式代码指示的格式展现。
n是上文的长度。
- Describe (F)
-
- Byte1('D')
-
标识该消息是一个Describe(描述)命令。
- Int32
-
以字节计的消息内容的长度,包括字节本身。
- Byte1
-
'
S'描述一个预备语句;或者 'P' 描述一个入口。 - String
-
要描述的预备语句或者入口的名字(或者一个空字符串,就会选取未命名的预备语句或者入口)。
- EmptyQueryResponse (B)
-
- Byte1('I')
-
标识这条消息是对一个空查询字符串的响应(这个消息替换了CommandComplete)。
- Int32(4)
-
以字节计的消息内容长度,包括它自己。
- ErrorResponse (B)
-
- Byte1('E')
-
标识该消息是一条错误。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
消息体由一个或多个标识域组成,后面跟着一个零字节作为终止符。域可以以任何顺序出现。对于每个域都有下面的东西:
- Byte1
-
一个标识域类型的代码;如果为零,这就是消息终止符并且不会跟着有字符串。目前定义的域类型在第 52.8 节列出。由于将来可能增加更多的域类型,所以前端应该默默地忽略未识别类型的域。
- String
-
域值。
- Execute (F)
-
- Byte1('E')
-
标识该消息是一个Execute命令。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- String
-
要执行的入口的名字(空字符串选择未命名的入口)。
- Int32
-
要返回的最大行数,如果入口包含返回行的查询(否则忽略)。零表示“无限制”。
- Flush (F)
-
- Byte1('H')
-
标识该消息是一条Flush命令。
- Int32(4)
-
以字节计的消息内容的长度,包括长度本身。
- FunctionCall (F)
-
- Byte1('F')
-
标识该消息是一个函数调用。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
- Int32
-
指定要调用的函数的对象ID(OID)。
- Int16
-
后面跟着的参数格式代码的数目(用下文的
C表示)。 它可以是零,表示没有参数,或者是所有参数都使用缺省格式(文本); 也可以是一,这种情况下声明的格式代码被应用于所有参数;或者它可以等于参数的实际个数。 -
Int16[
C] -
参数格式代码。目前每个必须是零(文本)或者一(二进制)
- Int16
-
指定提供给函数的参数个数。
然后,对每个参数都出现下面域对:
- Int32
-
以字节计的参数值的长度(不包括长度本身)。可以为零。一个特殊的例子是,-1表示一个NULL参数值。如果是NULL,则没有参数字节跟在后面。
-
Byte
n -
参数的值,格式由相关的格式代码指示。
n是上文的长度。
在最后一个参数之后,出现下面的域:
- Int16
-
函数结果的格式代码。目前必须是零(文本)或者一(二进制)。
- FunctionCallResponse (B)
-
- Byte1('V')
-
标识这条消息是一个函数调用结果。
- Int32
-
以字节计的消息内容长度,包括长度本身。
- Int32
-
以字节计的函数结果值的长度(不包括长度本身)。可以为零。一个特殊的情况是,-1表示NULL函数结果。如果是NULL则后面没有值字节跟随。
-
Byte
n -
函数结果的值,格式由相关联的格式代码指示。
n是上文的长度。
- GSSResponse (F)
-
- Byte1('p')
-
标识该消息是一个GSSAPI或SSPI响应。注意这也被用于SASL和口令响应消息。准确的消息类型可以从上下文中得出。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
-
Byte
n -
GSSAPI/SSPI相关的消息数据。
- NegotiateProtocolVersion (B)
-
- Byte1('v')
-
标识该消息是一个协议版本协商消息。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
- Int32
-
对于客户端请求的主协议版本,服务器能支持的最新的次协议版本。
- Int32
-
服务器无法识别的协议选项数目。
然后,对于服务器无法识别的协议选项,还有下列信息:
- String
-
选项名称。
- NoData (B)
-
- Byte1('n')
-
标识这条消息是一个无数据指示器。
- Int32(4)
-
以字节计的消息内容长度,包括长度本身。
- NoticeResponse (B)
-
- Byte1('N')
-
标识这条消息是一个通知。
- Int32
-
以字节计的消息内容长度,包括长度本身。
消息体由一个或多个标识域组成,后面跟着零字节作为中止符。域可以以任何顺序出现。对于每个域,都有下面的东西:
- Byte1
-
一个标识域类型的代码;如果为零,那么它就是消息终止符,并且后面不会跟着字符串。目前定义的域类型在第 52.8 节里列出。由于将来可能会增加更多域类型,所以前端应该将不能识别的域安静地忽略掉。
- String
-
域值。
- NotificationResponse (B)
-
- Byte1('A')
-
标识这条消息是一个通知响应。
- Int32
-
以字节计地消息内容地长度,包括长度本身。
- Int32
-
通知后端进程的进程ID。
- String
-
通知被抛出的通道的名字。
- String
-
从通知进程传递过来的“载荷”字符串。
- ParameterDescription (B)
-
- Byte1('t')
-
标识该消息是一个参数描述。
- Int32
-
以字节计的消息内容长度,包括长度本身。
- Int16
-
语句所使用的参数的个数(可以为零)。
然后,对每个参数,有下面的东西:
- Int32
-
指定参数数据类型的对象ID。
- ParameterStatus (B)
-
- Byte1('S')
-
标识这条消息是一个运行时参数的状态报告。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- String
-
被报告的运行时参数的名字。
- String
-
参数的当前值。
- Parse (F)
-
- Byte1('P')
-
标识该消息是一条Parse命令。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- String
-
目的预备语句的名字(空字符串选取未命名的预备语句)。
- String
-
要分析的查询字符串。
- Int16
-
指定的参数数据类型的数目(可以为零)。请注意这个参数并不表示可能在查询字符串里出现的参数个数, 只是前端希望预先为其指定类型的参数数目。
然后,对每个参数,有下面的东西:
- Int32
-
指定参数数据类型的对象ID。这里为零等效于不指定该类型。
- ParseComplete (B)
-
- Byte1('1')
-
标识该消息是一个Parse完成指示器。
- Int32(4)
-
以字节计的消息内容长度,包括长度自身。
- PasswordMessage (F)
-
- Byte1('p')
-
标识该消息是一个口令响应。注意这也被用于GSSAPI、SSPI以及SASL响应消息。确切的消息类型可以从上下文推出。
- Int32
-
以字节计的消息内容的长度,包括长度本身。
- String
-
口令(如果要求了,就是加密后的)。
- PortalSuspended (B)
-
- Byte1('s')
-
标识这条消息是一个入口暂停指示器。请注意这个消息只出现在达到一条Execute消息的行计数限制的时候。
- Int32(4)
-
以字节计的消息内容的长度,包括长度自身。
- Query (F)
-
- Byte1('Q')
-
标识该消息是一个简单查询。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- String
-
查询字符串自身。
- ReadyForQuery (B)
-
- Byte1('Z')
-
标识消息的类型。在后端为新的查询周期准备好的时候,总会发送 ReadyForQuery。
- Int32(5)
-
以字节计的消息内容的长度,包括长度本身。
- Byte1
-
当前后端事务状态指示器。可能的值是空闲状况下的'
I'(不在事务块里);在事务块里是'T'; 或者在一个失败的事务块里是'E'(在事务块结束之前,任何查询都将被拒绝)。
- RowDescription (B)
-
- Byte1('T')
-
标识该消息是一个行描述。
- Int32
-
以字节计的消息内容的长度,包括长度自身。
- Int16
-
指定在一个行里面的域的数目(可以为零)。
然后对于每个字段,有下面的东西:
- String
-
字段名字。
- Int32
-
如果域可以被标识为一个指定表的列,这里就是表的对象ID;否则就是零。
- Int16
-
如果该域可以被标识为一个指定表的列,这里就是该列的属性号;否则就是零。
- Int32
-
域数据类型的对象ID。
- Int16
-
数据类型尺寸(参阅
pg_type.typlen)。请注意负值表示变宽类型。 - Int32
-
类型修饰词(参阅
pg_attribute.atttypmod)。 修饰词的含义是类型相关的。 - Int16
-
用于该域的格式码。目前会是零(文本)或者一(二进制)。 在Describe语句的变体返回的RowDescription里,格式码还是未知的,因此总是零。
- SASLInitialResponse (F)
-
- Byte1('p')
-
标识该消息是一个初始SASL响应。注意这也被用于GSSAPI、SSPI以及口令响应消息。确切的消息类型可以从上下文推知。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
- String
-
客户端选择的SASL认证机制的名称。
- Int32
-
后面跟着的SASL机制相关的"Initial Client Response"的长度,如果没有Initial Response则为-1。
-
Byte
n -
SASL机制相关的"Initial Response"。
- SASLResponse (F)
-
- Byte1('p')
-
标识该消息是一个初始SASL响应。注意这也被用于GSSAPI、SSPI以及口令响应消息。确切的消息类型可以从上下文推知。
- Int32
-
消息内容的长度,以字节为单位,包括其自身。
-
Byte
n -
SASL机制相关的消息数据。
- SSLRequest (F)
-
- Int32(8)
-
以字节计的消息内容的长度,包括长度本身。
- Int32(80877103)
-
SSL请求码。选取的值在高16位里包含
1234,在低16位里包含5679(为了避免混淆,这个编码必须和任何协议版本号不同)。
- GSSENCRequest (F)
-
- Int32(8)
-
消息内容的长度以字节为单位,包括自己。
- Int32(80877104)
-
GSSAPI加密请求代码。选择该值以在高16位中包含
1234,并且在低16位中包含5680。 (为了避免混淆,此代码不得与任何协议版本号相同。)
- StartupMessage (F)
-
- Int32
-
以字节计的消息内容长度,包括长度自身。
- Int32(196608)
-
协议版本号。高16位是主版本号(对这里描述的协议而言是 3)。低16位是次版本号(对于这里描述的协议而言是 0)。
协议版本号后面跟着一个或多个参数名和值字符串的对。要求在最后一个名字/数值对后面有个零字节作为终止符。 参数可以以任意顺序出现。
user是必须的,其它都是可选的。每个参数是这样指定的:- String
-
参数名。目前可以识别的名字是:
-
user -
用于连接的数据库用户名。必须;无缺省。
-
database -
要连接的数据库。缺省是用户名。
-
options -
给后端的命令行参数(这个特性已经废弃,更好的方法是设置单独的运行时参数)。 这个字符串中的空格会被当做参数的分隔符,除非用一个反斜线(
\) 对它转义。写\\可表示一个而字面意义上的反斜线。 -
replication -
用于连入流复制模式,其中可以发出复制命令的一个小型集合而不是SQL语句。值可以是
true、false或者database,默认值是false。详情请参考第 52.4 节。
除了上述参数之外,还可以列出其他参数。以
_pq_.开头的参数名被保留给协议扩展之用,而其他的参数名被当做在后端开始时要设置的运行时参数。这类设置将在后端启动期间被应用(如果有命令行参数,则在解析完命令行参数之后)并且将作为会话的默认值。 -
- String
-
参数值。
- Sync (F)
-
- Byte1('S')
-
表示该消息为一条 Sync 命令。
- Int32(4)
-
以字节计的消息内容的长度,包括长度自身。
- Terminate (F)
-
- Byte1('X')
-
标识本消息是一个终止。
- Int32(4)
-
以字节计的消息内容的长度,包括长度自身。