系列目录
深度解析 PostgreSQL Protocol v3.0 — 综述(上)
深度解析 PostgreSQL Protocol v3.0 — 综述(下)
深度解析 PostgreSQL Protocol v3.0 — 扩展查询(上)
深度解析 PostgreSQL Protocol v3.0 — 扩展查询(下)
引言
PostgreSQL 使用基于消息的协议在前端(客户端)和后端(服务器)之间进行通信。该协议通过 TCP/IP 和 Unix 域套接字支持。
《深度解析 PostgreSQL Protocol v3.0》系列技术贴,将带大家深度了解 PostgreSQL Protocol v3.0(在 PostgreSQL 7.4 及更高版本中实现,有关早期协议版本的描述请参考 PostgreSQL 文档的早期版本,该系列文章不予赘述)相关的消息传输格式和格式码、消息支持的数据类型、消息的格式、协议交互流程、错误消息和通知消息、支持的子协议等,相关的代码解读基于 PostgreSQL 代码仓库的 REL_14_STABLE 分支。
一、扩展查询可能出现的消息
二、扩展查询涉及消息的格式
以下是在扩展查询过程中可能出现的消息,下面进行详细介绍。
1. Parse(F:‘P’)
Parse 消息格式如下:
- Byte1(‘P’)
将消息标识为 Parse 命令。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- String
目标准备语句的名称(空字符串选择未命名的准备语句)。
- String
要解析的查询字符串。
- int16
指定的参数数据类型的数目(可以为 0)。请注意,这并不是可能出现在查询字符串中的参数数量的指示,只是前端希望为其预先指定数据类型的数量。
然后,对于每一个参数都有以下数据类型 OID:
- Int32
指定参数数据类型的 OID。在此处放置 0 相当于未指定类型。
2. ParseComplete(B:‘1’)
ParseComplete 消息格式如下:
- Byte1(‘1’)
将消息标识为 ParseComplete 消息。
- Int32(4)
消息内容的字节长度,包括自身 4 个字节。始终为 4。
3. Bind(F:‘B’)
Bind 消息格式如下:
- Byte1(‘B’)
将消息标识为 Bind 消息。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- String
目标门户的名称(空字符串选择未命名的门户)。
- String
源准备语句的名称(空字符串选择未命名的准备语句)。
- Int16
后续的参数格式代码的数量(下面用C表示)。值可以是:
(1)0,表示没有参数或参数都使用默认格式(text);
(2)1,在这种情况下,指定的格式代码被应用于所有参数;
(3)值等于参数的实际数量。
- Int16[C]
参数格式代码。目前数组每个元素的值必须为 0(text)或 1(binary)。
- Int16
后面的参数值的数目(可能为 0)。值必须与查询所需的参数数量相匹配。
接下来,将为每个参数构建以下字段对:
- Int32
参数值的长度,以字节为单位(此计数不包括其自身)。值可以为零。作为一种特殊情况,-1 表示 NULL 参数值。值为 NULL 情况下,后面没有值字节。
- Byten
参数的值,格式由关联的格式代码指示。n 是上述参数值的长度。
在最后一个参数之后,将显示以下两个字段:
- Int16
后面的结果列格式代码的数量(下面用 R 表示)。值可以是:
(1)0,表示没有结果列,或者结果列都应该使用默认格式(text);
(2)1,在这种情况下,指定的格式代码被应用于所有结果列(如果有结果列的话);
(3)等于查询的结果列的实际数量。
- Int16[R]
结果列格式代码。目前数组每个元素的值必须为0(text)或1(binary)。
4. BindComplete(B:‘2’)
BindComplete 消息格式如下:
- Byte1(‘2’)
将消息标识为 BindComplete 消息。
- Int32(4)
消息内容的字节长度,包括自身 4 个字节。始终为 4。
5. Describe(F:‘D’)
Describe 消息格式如下:
- Byte1(‘D’)
将消息标识为 Describe 消息。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- Byte1
指示 Describe 描述的对象类型。可能的值为:‘S’,表示描述准备语句;‘P’,表示描述门户。
- String
要描述的准备语句或门户的名称(空字符串选择未命名的准备语句或门户)。
描述门户 Portal 的消息格式如下:
描述准备语句的消息格式如下:
6. RowDescription(B:‘T’)
RowDescription 消息格式如下:
- Byte1(‘T’)
将消息标识为行描述。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- Int16
指定一行中的字段数(可以为 0)。
对于行描述中的每个字段,都有以下 7 部分内容:
- String
字段名称
- Int32
如果字段可以被标识为特定表的列,则值为该表的对象 ID;否则为 0。
- Int16
如果该字段可以标识为特定表的列,则值为该列的属性编号;否则为 0。
- Int32
字段数据类型的对象 ID。
- Int16
数据类型大小(可以参考 pg_type.typlen)。需要注意的是,负值表示可变宽度类型。
- Int32
类型修饰符(可以参考 pg_attribute.atttypmod)。修饰符的含义是特定于数据类型的。
- Int16
字段的格式代码。目前,只能是 0(文本)或 1(二进制)。在从 Describe 语句请求返回的 RowDescription 中,格式代码还未知,并且始终为零。
蓝色背景的部分,是每个列的详细描述。浅灰色背景的部分是可选的,格式是蓝色部分的重复。
7. NoData(B:‘n’)
NoData 消息格式如下:
- Byte1(‘n’)
将消息标识为 NoData 消息。
- Int32(4)
消息内容的字节长度,包括自身 4 个字节。值始终为 4。
8. ParameterDescription(B:‘t’)
ParameterDescription 消息格式如下:
- Byte1(‘t’)
将消息标识为 ParameterDescription 消息。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- Int16
语句使用的参数数量(可以为 0)。
然后,对于每个参数,都有以下内容:
- Int32
指定参数数据类型的对象 ID。
如果语句使用的参数数量为 0,则没有后续的参数数据类型的内容。蓝色背景的部分,是每个参数的数据类型对象 ID,是可选的。浅灰色背景的部分是可选的,格式是蓝色部分的重复。
9. Execute(F:‘E’)
Execute 消息格式如下:
- Byte1(‘E’)
将消息标识为 Execute 消息。
- Int32
消息内容的字节长度,包括自身 4 个字节。
- String




