如何在Emacs中将大于4k的查询从SQL缓冲区发送到sql-mysql缓冲区?(涉及IT技术)

23
我经常在Emacs的sql-mysql模式中遇到麻烦,我想知道是否有解决方法或更好的解决方法。每当我尝试从sql-mode缓冲区将查询发送到活动的SQL进程缓冲区时,该查询不能超过4k。如果它大于4k,似乎会插入某种断点 - 可能是换行符 - 这会导致mysql解释器在以下行上报错。
sql-mysql由sql.el实现,并使用函数sql-send-region将查询区域(或整个缓冲区)发送到所选的SQL进程缓冲区。 sql-send-region调用comint-send-region,后者又调用process-send-region。 process-send-region是一个C函数,它调用Emacs源码中的src/process.c中的send_process。
看起来这可能只是IPC管道上4k缓冲区产生的限制。由于似乎需要进行内核编写才能更改此大小,因此这不是一个很好的答案。
我猜困惑的原因是如果通过管道发送的SQL大于4k,则mysql客户端为什么无法正确地重新组合它。有什么想法吗?
Emacs版本:GNU Emacs 23.3.1(x86_64-pc-linux-gnu,GTK + Version 2.24.10)于2012-03-25在allspice上修改的Debian
mysql-V:mysql Ver 14.14 Distrib 5.5.24,用于debian-linux-gnu(x86_64),使用readline 6.2
Sql Mysql选项:-A -C -n(注意我尝试过有或没有-n(未缓冲),两者都无法解决此问题)

顺便说一句,我目前发现的最好的解决方法是直接从保存的文件中获取查询,即“. sql_long_query.sql”。然而,当尝试调试查询或多查询文件的部分时,这样做会相当烦人。这就是为什么我希望能够使用sql-send-region方法,即使对于大于4k字符的区域也可以。 - Ryan M
还要注意,仅仅复制和粘贴一个超过4k的查询到sql-mysql缓冲区中会遇到同样的问题。这更证明了问题出现在send_process C函数级别或以下。 - Ryan M
你能尝试使用rlwrap运行emacs吗? - ramrunner
@ramrunner,这需要从终端运行emacs,这通常(我个人认为)并不理想。 - Squidly
我写了一个小脚本来包装mysql调用rlwrap。从shell中运行得很好。但是在emacs中却没有这样的运气。我一直收到以下错误信息: rlwrap:糟糕,崩溃了(捕获了SIGFPE)-这不应该发生! - Ryan M
显示剩余4条评论
1个回答

5
我怀疑罪魁祸首是Emacs的进程通信代码,它被comint使用,用于分配PTY以与进程通信。虽然这些对于交互式工作很有用,因为它们允许作业控制,但它们在没有中间换行符的情况下可以传输的数据量也是有限的。 Emacs还可以被告知使用管道,这种方法没有这种限制。
要测试这一点,请启动一个全新的Emacs,评估M-:(setq process-connection-type nil),并开始sql-mysql。如果问题消失了,那么这就是罪魁祸首。在这种情况下,您将想要使用类似以下的东西:
(add-hook 'sql-mysql-mode-hook
          (lambda ()
            (set (make-local-variable 'process-connection-type) nil)))

为了确保process-connection-type仅在MySQL交互缓冲区中重置。


编辑

根据http://tinyurl.com/car439o/,Emacs不再使用换行符+EOF对长的PTY输出进行中断。尽管提交是从2010-04-13开始的,但它只出现在2012年发布的Emacs 24中。这解释了为什么问题在24.2.1中似乎无法重现。如果您使用的是24之前的Emacs,请尝试升级。


看起来在 PTY 上关闭 ICANON 可能会抑制它在每个缓冲区文本结束时发送一个新行。我们如何在从 Emacs 分配 PTY 时清除 PTY 上的 ICANON 标志? - Ryan M
仅供参考,我还没有颁发赏金的原因是管道连接的mysql退出错误行为。这是一种比原始问题更糟糕的治疗方法,即更方便地开发大型SQL查询。每次出现错误都必须重新启动mysql,甚至比输入\。<SQL文件>到sql-mysql缓冲区更不方便。我们更接近了,但还不足以接受答案。 - Ryan M
1
有趣的是,我无法使用PTY在shell模式下重复您遇到的问题,例如使用zsh。 我使用“ C-u 100000 a RET”发送长度为100k的命令,并且(等待Emacs解析输出一段时间后),zsh生成的“ command aaaaaaaaa ... too long”错误消息中正好有100k个a。 如果zsh能够从Emacs接收正确的输出,为什么mysql不能呢? - user4815162342
@RyanM 请看一下修改后的内容;你正在使用哪个版本的Emacs? - user4815162342
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/16566/discussion-between-ryan-m-and-user4815162342 - Ryan M
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接