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
, 其中oid
rows
rows
是已被插入的行数。如果rows
为1并且目标表已有OIDs,oid
为已插入行的对象ID;但是OIDs 系统列已经不再被支持;因此oid
始终为 0。对于
DELETE
命令,该标记是DELETE
, 其中rows
rows
是已被删除的行数。对于
UPDATE
命令,该标记是UPDATE
,其中rows
rows
是已被更新的行数。对于
SELECT
或CREATE TABLE AS
命令,该标记是SELECT
,其中rows
rows
是被检索的行数。对于
MOVE
命令,该标记是MOVE
,其中rows
rows
是游标位置被移动的行数。对于
FETCH
命令,该标记是FETCH
,其中rows
rows
是已从游标中检索出来的行数。对于
COPY
命令,该标记是COPY
,其中rows
rows
是已拷贝的行数(注意,行计数只在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)
-
以字节计的消息内容的长度,包括长度自身。