Skip to content

55.7. 消息格式# ​

本节介绍每条消息的详细格式。每条消息都标记为可由前端 (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

加密密码时要使用的盐。

AuthenticationGSS (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32(8)

包括自身在内的消息内容长度(以字节为单位)。

Int32(7)

指定需要 GSSAPI 身份验证。

AuthenticationGSSContinue (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32(8)

指定此消息包含 GSSAPI 或 SSPI 数据。

Byten

GSSAPI 或 SSPI 身份验证数据。

AuthenticationSSPI (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32(8)

包括自身在内的消息内容长度(以字节为单位)。

Int32(9)

指定需要 SSPI 身份验证。

AuthenticationSASL (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32(10)

指定需要 SASL 身份验证。

消息正文是 SASL 身份验证机制列表,按服务器的优先顺序排列。最后一个身份验证机制名称后需要一个零字节作为终止符。对于每种机制,都有以下内容

String

SASL 身份验证机制的名称。

AuthenticationSASLContinue (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32(11)

指定此消息包含 SASL 质询。

Byten

SASL 数据,特定于正在使用的 SASL 机制。

AuthenticationSASLFinal (B) #
Byte1('R')

将消息标识为身份验证请求。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32(12)

指定 SASL 身份验证已完成。

Byten

SASL 结果“附加数据”,特定于正在使用的 SASL 机制。

BackendKeyData (B) #
Byte1('K')

将消息标识为取消密钥数据。如果前端希望以后能够发出 CancelRequest 消息,则必须保存这些值。

Int32(12)

包括自身在内的消息内容长度(以字节为单位)。

Int32

此后端的进程 ID。

Int32

此后端的密钥。

Bind (F) #
Byte1('B')

将消息标识为 Bind 命令。

Int32

包括自身在内的消息内容长度(以字节为单位)。

String

目标门户的名称(空字符串选择未命名门户)。

String

源准备语句的名称(空字符串选择未命名的准备语句)。

Int16

后面跟随的参数格式代码数(下面用C表示)。可以为零,表示没有参数或所有参数都使用默认格式(文本);或为一,在这种情况下,指定的格式代码应用于所有参数;或者可以等于参数的实际数量。

Int16[C]

参数格式代码。每个目前必须为零(文本)或一(二进制)。

Int16

后面跟随的参数值数(可能为零)。这必须与查询所需的的参数数相匹配。

接下来,对于每个参数,出现以下字段对

Int32

参数值长度,以字节为单位(此计数不包括它本身)。可以为零。作为特殊情况,-1 表示 NULL 参数值。在 NULL 情况下,没有值字节跟随。

Byten

参数值,采用关联格式代码指示的格式。n 是上述长度。

在最后一个参数之后,出现以下字段

Int16

后面跟随的结果列格式代码数(下面用R表示)。可以为零,表示没有结果列或所有结果列都应使用默认格式(文本);或为一,在这种情况下,指定的格式代码应用于所有结果列(如果有);或者可以等于查询的实际结果列数。

Int16[R]

结果列格式代码。每个目前必须为零(文本)或一(二进制)。

BindComplete (B) #
Byte1('2')

将消息标识为绑定完成指示符。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

CancelRequest (F) #
Int32(16)

包括自身在内的消息内容长度(以字节为单位)。

Int32(80877102)

取消请求代码。该值被选为在最高有效 16 位中包含1234,在最低有效 16 位中包含5678。(为了避免混淆,此代码不得与任何协议版本号相同。)

Int32

目标后端的进程 ID。

Int32

目标后端的密钥。

Close (F) #
Byte1('C')

将消息标识为 Close 命令。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Byte1

'S' 用于关闭已准备好的语句;或 'P' 用于关闭门户。

String

要关闭的已准备好的语句或门户的名称(空字符串选择未命名的已准备好的语句或门户)。

CloseComplete (B) #
Byte1('3')

将消息标识为 Close-complete 指示符。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

CommandComplete (B) #
Byte1('C')

将消息标识为命令完成响应。

Int32

包括自身在内的消息内容长度(以字节为单位)。

String

命令标记。这通常是一个单词,用于标识已完成的 SQL 命令。

对于 INSERT 命令,标记为 INSERT oid rows,其中 rows 是插入的行数。如果 rows 为 1 且目标表具有 OID,则 oid 用于表示插入行的对象 ID,但 OID 系统列不再受支持;因此 oid 始终为 0。

对于 DELETE 命令,标记为 DELETE rows,其中 rows 是已删除的行数。

对于 UPDATE 命令,标记为 UPDATE rows,其中 rows 是已更新的行数。

对于 MERGE 命令,标记为 MERGE 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

包括自身在内的消息内容长度(以字节为单位)。

Byten

构成 COPY 数据流一部分的数据。后端发送的消息将始终对应于单数据行,但前端发送的消息可能会任意划分数据流。

CopyDone (F & B) #
Byte1('c')

标识消息为 COPY 完成指示符。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

CopyFail (F) #
Byte1('f')

标识消息为 COPY 失败指示符。

Int32

包括自身在内的消息内容长度(以字节为单位)。

String

报告为失败原因的错误消息。

CopyInResponse (B) #
Byte1('G')

标识消息为开始复制响应。现在前端必须发送复制数据(如果没有准备好这样做,请发送 CopyFail 消息)。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int8

0 表示整体 COPY 格式为文本(行由换行符分隔,列由分隔符分隔,等等)。1 表示整体复制格式为二进制(类似于 DataRow 格式)。有关更多信息,请参阅 COPY。

Int16

要复制的数据中的列数(如下用 N 表示)。

Int16[N]

用于每列的格式代码。每个目前必须为零(文本)或一(二进制)。如果整体复制格式为文本,则所有格式代码都必须为零。

CopyOutResponse (B) #
Byte1('H')

标识消息为开始复制响应。此消息后将紧跟复制数据。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int8

0 表示整体 COPY 格式为文本(行由换行符分隔,列由分隔符分隔,等等)。1 表示整体复制格式为二进制(类似于 DataRow 格式)。有关更多信息,请参阅 COPY。

Int16

要复制的数据中的列数(如下用 N 表示)。

Int16[N]

用于每列的格式代码。每个目前必须为零(文本)或一(二进制)。如果整体复制格式为文本,则所有格式代码都必须为零。

CopyBothResponse (B) #
Byte1('W')

标识消息为开始同时复制响应。此消息仅用于流复制。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int8

0 表示整体 COPY 格式为文本(行由换行符分隔,列由分隔符分隔,等等)。1 表示整体复制格式为二进制(类似于 DataRow 格式)。有关更多信息,请参阅 COPY。

Int16

要复制的数据中的列数(如下用 N 表示)。

Int16[N]

用于每列的格式代码。每个目前必须为零(文本)或一(二进制)。如果整体复制格式为文本,则所有格式代码都必须为零。

DataRow (B) #
Byte1('D')

标识消息为数据行。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int16

后面跟随的列值数(可能为零)。

接下来,为每一列显示以下字段对

Int32

列值的长度(以字节为单位,此计数不包括自身)。可以为零。作为特殊情况,-1 表示 NULL 列值。在 NULL 情况下,不会有值字节跟随。

Byten

列的值,格式由关联的格式代码指示。n 是上述长度。

Describe (F) #
Byte1('D')

将消息标识为 Describe 命令。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Byte1

'S' 用于描述已准备好的语句;或 'P' 用于描述门户。

String

要描述的已准备好的语句或门户的名称(空字符串选择未命名的已准备好的语句或门户)。

EmptyQueryResponse (B) #
Byte1('I')

将消息标识为对空查询字符串的响应。(这代替了 CommandComplete。)

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

ErrorResponse (B) #
Byte1('E')

将消息标识为错误。

Int32

包括自身在内的消息内容长度(以字节为单位)。

消息正文由一个或多个已标识的字段组成,后跟一个零字节作为终止符。字段可以按任何顺序出现。对于每个字段,都有以下内容

Byte1

一个标识字段类型的代码;如果为零,则这是消息终止符,后面没有字符串。当前定义的字段类型列于 第 55.8 节 中。由于将来可能会添加更多字段类型,因此前端应静默忽略无法识别的类型的字段。

String

字段值。

Execute (F) #
Byte1('E')

将消息标识为 Execute 命令。

Int32

包括自身在内的消息内容长度(以字节为单位)。

String

要执行的门户的名称(空字符串选择未命名的门户)。

Int32

要返回的最大行数,如果门户包含返回行的查询(否则忽略)。零表示 “无限制”。

Flush (F) #
Byte1('H')

将消息标识为 Flush 命令。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

FunctionCall (F) #
Byte1('F')

将消息标识为函数调用。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32

指定要调用的函数的对象 ID。

Int16

后面跟的参数格式代码数量(以下表示为 C)。可以为零,表示没有参数或所有参数都使用默认格式(文本);或为一,在这种情况下,指定的格式代码应用于所有参数;或者可以等于实际参数数量。

Int16[C]

参数格式代码。每个目前必须为零(文本)或一(二进制)。

Int16

指定提供给函数的参数数量。

接下来,每个参数都会出现以下一对字段

Int32

参数值的长度,以字节为单位(此计数不包括它本身)。可以为零。作为特例,-1 表示 NULL 参数值。在 NULL 情况下,不会跟随任何值字节。

Byten

参数的值,格式由关联的格式代码指示。n 是上述长度。

在最后一个参数之后,会出现以下字段

Int16

函数结果的格式代码。目前必须为零(文本)或一(二进制)。

FunctionCallResponse (B) #
Byte1('V')

将消息标识为函数调用结果。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32

函数结果值的长度,以字节为单位(此计数不包括它本身)。可以为零。作为特例,-1 表示 NULL 函数结果。在 NULL 情况下,不会跟随任何值字节。

Byten

函数结果的值,格式由关联的格式代码指示。n 是上述长度。

GSSENCRequest (F) #
Int32(8)

包括自身在内的消息内容长度(以字节为单位)。

Int32(80877104)

加密请求代码。该值被选为在最高有效 16 位中包含 1234,在最低有效 16 位中包含 5680。(为避免混淆,此代码不得与任何协议版本号相同。)

GSSResponse (F) #
Byte1('p')

将消息标识为 GSSAPI 或 SSPI 响应。请注意,这也用于 SASL 和密码响应消息。可以从上下文中推断确切的消息类型。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Byten

GSSAPI/SSPI 特定的消息数据。

NegotiateProtocolVersion (B) #
Byte1('v')

将消息标识为协议版本协商消息。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32

服务器为客户端请求的主协议版本支持的最新次要协议版本。

Int32

服务器未识别的协议选项数。

然后,对于服务器未识别的协议选项,有以下内容

String

选项名称。

NoData (B) #
Byte1('n')

将消息标识为无数据指示符。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

NoticeResponse (B) #
Byte1('N')

将消息标识为通知。

Int32

包括自身在内的消息内容长度(以字节为单位)。

消息正文由一个或多个已标识的字段组成,后跟一个零字节作为终止符。字段可以按任何顺序出现。对于每个字段,都有以下内容

Byte1

一个标识字段类型的代码;如果为零,则这是消息终止符,后面没有字符串。当前定义的字段类型列于 第 55.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')

将消息标识为解析完成指示符。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

PasswordMessage (F) #
Byte1('p')

将消息标识为密码响应。请注意,这也用于 GSSAPI、SSPI 和 SASL 响应消息。确切的消息类型可以从上下文中推断出来。

Int32

包括自身在内的消息内容长度(以字节为单位)。

String

密码(已加密,如果请求的话)。

PortalSuspended (B) #
Byte1('s')

将消息标识为门户暂停指示符。请注意,只有在达到执行消息的行计数限制时才会出现此消息。

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 机制特定“初始客户端响应”的长度,如果没有初始响应,则为 -1。

Byten

SASL 机制特定的“初始响应”。

SASLResponse (F) #
Byte1('p')

将消息标识为 SASL 响应。请注意,这也用于 GSSAPI、SSPI 和密码响应消息。确切的消息类型可以从上下文中推断出来。

Int32

包括自身在内的消息内容长度(以字节为单位)。

Byten

SASL 机制特定消息数据。

SSLRequest (F) #
Int32(8)

包括自身在内的消息内容长度(以字节为单位)。

Int32(80877103)

请求代码。选择该值是为了在最高有效位中包含 1234,在最低有效位中包含 5679。(为避免混淆,此代码不得与任何协议版本号相同。)

StartupMessage (F) #
Int32

包括自身在内的消息内容长度(以字节为单位)。

Int32(196608)

协议版本号。最高有效位是主版本号(此处描述的协议为 3)。最低有效位是次要版本号(此处描述的协议为 0)。

协议版本号后跟一个或多个参数名称和值字符串。最后一个名称/值对后需要一个零字节作为终止符。参数可以按任何顺序出现。需要 user,其他参数是可选的。每个参数指定为

String

参数名称。当前识别的名称是

user

用作连接的数据库用户名。必需;没有默认值。

database

要连接的数据库。默认为用户名。

options

后端的命令行参数。(这已被弃用,建议设置单独的运行时参数。)此字符串中的空格被认为是分隔参数,除非使用反斜杠 (\) 转义;编写 \\ 以表示一个文字反斜杠。

replication

用于以流复制模式连接,其中可以发出少量复制命令,而不是 SQL 语句。值可以是 true、false 或 database,默认值为 false。有关详细信息,请参见第 55.4 节。

除了上述内容外,还可以列出其他参数。以 _pq_. 开头的参数名称保留为协议扩展使用,而其他参数则视为在后端启动时设置的运行时参数。此类设置将在后端启动期间(在解析命令行参数(如果有)之后)应用,并将充当会话默认值。

String

参数值。

同步 (F) #
Byte1('S')

将消息标识为同步命令。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。

终止 (F) #
Byte1('X')

将消息标识为终止。

Int32(4)

包括自身在内的消息内容长度(以字节为单位)。