4.4. 消息格式

本节描述各种消息的详细格式.每种消息都可以由一个前端 (F), 一个后端 (B)或者两者(F & B)发送.

AsciiRow (B)

Byte1('D')

标识消息是一个 ASCII 数据行. (一个前面的 RowDescription 消息定义该行里面的字段数 和它们的数据类型.)

Byten

一个每个位对应(数据)行里一个字段的位图. 第一字段对应第一字节的位 7 (MSB,最高位), 第二字段对应第一字节位6, 第八字段对应第一字节位 0 (LSB,最低位), 第九字段对应第二字节的位7,等等.如果对应域的值不为 NULL, 对应位设置为1,如果字段的个数不为8的倍数, 位图最后一个字节余下的位就没有用.

然后,每个非空的字段值(non-NULL),有下面规则:

Int32

声明字段值的尺寸,包括尺寸本身.

Byten

声明以 ASCII 字符表示的字段值本身. n 是上面的尺寸减 4. 在字段数据里面没有结尾的 '\0'; 如果前端希望有个结束符,它必须自己追加一个.

AuthenticationOk (B)

Byte1('R')

标识该消息是一条认证请求.

Int32(0)

声明该认证是成功的.

AuthenticationKerberosV4 (B)

Byte1('R')

标识该消息是一条认证请求.

Int32(1)

声明需要 Kerberos V4 认证.

AuthenticationKerberosV5 (B)

Byte1('R')

标识该消息是一条认证请求.

Int32(2)

声明需要 Kerberos V5 认证.

AuthenticationUnencryptedPassword (B)

Byte1('R')

标识该消息是一条认证请求.

Int32(3)

声明需要一个未加密的口令.

AuthenticationEncryptedPassword (B)

Byte1('R')

标识该消息是一条认证请求.

Int32(4)

声明需要一个加密的口令.

Byte2

加密口令使用的'种子'(salt).

BackendKeyData (B)

Byte1('K')

标识该消息是一个取消键字数据. 如果前端希望能够在稍后发出 CancelRequest 消息, 那么它必须保存这个值.

Int32

后端的进程号(PID).

Int32

此后端的密钥(secret key ).

BinaryRow (B)

Byte1('B')

标识消息为为二进制(数据)行. (一个前面的 RowDescription 消息定义数据行里的字段数和它们的数据类型.)

Byten

一个每个位对应(数据)行里一个字段的位图. 第一字段对应第一字节的位7 (MSB,最高位), 第二字段对应第一字节位6, 第八字段对应第一字节位 0 (LSB,最低位), 第九字段对应第二字节的位7,等等.如果对应域的值不为 NULL, 对应位设置为1,如果字段的个数不为8的倍数, 位图最后一个字节余下的位就没有用.

然后,每个非空的字段值(non-NULL),有下面规则:

Int32

声明字段值的尺寸,不包括尺寸本身.

Byten

以二进制格式声明字段本身的值. n 就是上面的尺寸.

CancelRequest (F)

Int32(16)

以字节计的包尺寸.

Int32(80877102)

取消请求代码.选这个值是为了在高16位包含 "1234", 低16位包含 "5678". (要避免混乱,这个代码必须与协议版本号不同.)

Int32

目标后端的进程号(PID).

Int32

目标后端的密钥(secret key ).

CompletedResponse (B)

Byte1('C')

标识此消息是一个完成响应.

String

命令标记. 它通常是一个单字,标识完成了哪条 SQL 命令.

对于 INSERT 命令,标记是 INSERT oid rows,这里的 rows 是插入的行数, 如果 rows 是 1, 那么 oid 是插入的行的对象标识(ID), 否则 oid 为 0.

对于 DELETE 命令,标记是 DELETE rows, 这里的 rows 是删除的行数.

对于 UPDATE 命令,标记是 UPDATE rows, 这里的 rows 是更新的行数.

CopyDataRows (B & F)

这是一个行的流,这里每行都是一个 Byte1('\n') 结尾的. 后面顺序跟着 Byte1('\\'),Byte1('.'),Byte1('\n').

CopyInResponse (B)

Byte1('G')

标识这条消息是一条 Start Copy In (开始拷贝进入)响应消息. 前端现在必须发送一条 CopyDataRows 消息.

CopyOutResponse (B)

Byte1('H')

标识这条消息是一条 Start Copy Out (开始拷贝进出)响应消息. 这条消息后面将跟着一条 CopyDataRows 消息.

CursorResponse (B)

Byte1('P')

标识这条消息是一条游标响应消息.

String

游标的名称.如果游标是隐含的,这个地方会是"空白" ("blank").

EmptyQueryResponse (B)

Byte1('I')

标识这条消息是对一个空查询字串的响应.

String("")

没有用.

EncryptedPasswordPacket (F)

Int32

以字节记的包的尺寸.

String

加密了(使用 MD5 或 crypt())的口令.

ErrorResponse (B)

Byte1('E')

标识消息是一条错误.

String

错误消息本身.

FunctionCall (F)

Byte1('F')

标识消息是一个函数调用.

String("")

未使用.

Int32

声明待调用的函数的对象标识(OID).

Int32

声明提供给函数的参数个数.

然后,每个参数用下面格式声明:

Int32

声明参数值的尺寸,除去尺寸本身的长度.

Byten

声明以二进制格式表示的字段值本身. n 是上面的尺寸.

FunctionResultResponse (B)

Byte1('V')

标识这条消息是函数调用结果.

Byte1('G')

声明返回了一个非空结果.

Int32

声明结果值的尺寸,除去尺寸本身长度.

Byten

声明二进制格式表示的结果值本身. n 是上面的尺寸.

Byte1('0')

未用.(严格的说,FunctionResultResponse 和 FunctionVoidResponse 都是一样的东西, 只不过消息里有一些可选的部分.)

FunctionVoidResponse (B)

Byte1('V')

标识这条消息是一个函数调用结果.

Byte1('0')

声明返回了一个空结果.

NoticeResponse (B)

Byte1('N')

标识消息是一个通知.

String

通知消息本身.

NotificationResponse (B)

Byte1('A')

标识消息是一个通知响应.

Int32

发出通知的后端进程的进程号(PID).

String

生成通知的条件名.

Query (F)

Byte1('Q')

标识此消息是一条查询.

String

查询字串本身.

ReadyForQuery (B)

Byte1('Z')

标识消息类型.当后端准备好进入一个新的查询循环时, 它发送一条 ReadyForQuery.

RowDescription (B)

Byte1('T')

标识消息是一个行描述消息.

Int16

声明一行里的字段数(可以是零).

然后每个字段,用下面格式表示:

String

声明字段名称.

Int32

声明字段的对象标识(OID).

Int16

声明类型尺寸.

Int32

声明类型修饰词.

SSLRequest (F)

Int32(8)

按字节记的包尺寸.

Int32(80877103)

SSL 请求码.选择的值是在高 16 位包含 1234,而 在低 16 位包含 5679.(为避免混淆,这个码必需与任何 协议版本号相区别.)

StartupPacket (F)

Int32(296)

以字节计的包尺寸.

Int32

协议版本号.最高16位是主版本号.低16位是次版本号.

LimString64

数据库名,为空时缺省是用户名.

LimString32

用户名.

LimString64

由服务器传递给后端子进程的任何附加命令行参数.

LimString64

未使用.

LimString64

后端用于调试信息输出的可选 tty (控制台). (目前还不支持这个字段,并将其忽略.)

Terminate (F)

Byte1('X')

标识这条消息是终止消息.

UnencryptedPasswordPacket (F)

Int32

以字节计的包尺寸.

String

未加密的口令.