psql \e 的鲁莽行为

Erw*_*ter 7 postgresql psql

psql 13.2 退出编辑器时,无论退出编辑器后如何,都会执行查询缓冲区 - 在这种情况下,缓冲区现在可能保存最近执行的 SQL 查询。

重现:

  1. vim使用\e\e filenamepsql控制台启动编辑器(在我的情况下)。
  2. 输入与否,没有区别。
  3. 取消编辑:q(或:q!强制)

预期行为:回到启动编辑器之前的状态。(我取消了编辑!)
观察到的行为:重新执行上次执行的 SQL 查询。

似乎发生了什么\e

  1. 它执行(相当于)\p,因此当前查询缓冲区包含前一个命令,当它为空时。(编辑文件时用户看不到!) 手册\p

    \p 或者 \print

    将当前查询缓冲区打印到标准输出。如果当前查询缓冲区为空,则打印最近执行的查询。

  2. 启动编辑器。如果提供了文件名,则加载文件,否则加载查询缓冲区。

  3. 如果编辑器以写入结束,则将结果复制到查询缓冲区。
    如果编辑被取消(:q在 vim 中),不要覆盖查询缓冲区。(它现在保存了之前的命令!)

  4. 执行查询缓冲区。或者,准确地说,这样做:

行为似乎可以\p(只是复制查询缓冲区,没有造成任何伤害),但不能\e执行,它可以执行我什至没有看到的命令。

这是一个错误吗?
无论哪种方式,我至少想在离开编辑器时禁用自动执行。但这似乎不可能。或者我错过了什么?

Lau*_*lbe 6

作为对此问题的反应,这已在 v14 中修复。答案的其余部分指的是 v14 之前的行为:

这是(有点)记录在案

如果filename指定,则文件被编辑;编辑器退出后,文件的内容被复制到当前查询缓冲区中。如果没有filename给出,当前查询缓冲区被复制到一个临时文件,然后以相同的方式编辑。或者,如果当前查询缓冲区为空,则将最近执行的查询复制到临时文件并以相同方式进行编辑。

然后根据 psql 的正常规则重新解析查询缓冲区的新内容,将整个缓冲区视为一行。

如果不保存就退出编辑器,则执行的是当前查询缓冲区或最近执行的查询。

我同意你的看法,这很烦人,而且你不是我听到抱怨的第一个人。

在编辑脚本时,这种行为显然违反了“最小惊讶原则”:

test=> \! cat q.sql
SELECT 99;

test=> SELECT 42;
 ?column? 
----------
       42
(1 row)

test=> \e q.sql
 ?column? 
----------
       42
(1 row)
Run Code Online (Sandbox Code Playgroud)