DWIM mode for psql

Started by Thomas Munroalmost 7 years ago6 messages
#1Thomas Munro
thomas.munro@gmail.com
1 attachment(s)

Hello,

Building on the excellent work begun by commit e529cd4ffa60, I would
like to propose a do-what-I-mean mode for psql. Please find a POC
patch attached. It works like this:

postgres=# select datnaam from pg_database where ooid = 12917;
ERROR: column "datnaam" does not exist
LINE 1: select datnaam from pg_database where ooid = 12917;
^
HINT: Perhaps you meant to reference the column "pg_database.datname".
postgres=# YES
datname
----------
postgres
(1 row)

As you can see, by "shouting" a new keyword at the computer, it will
take its own hint and run the corrected query. To avoid having to do
this in two steps, you can also shout the whole query for the same
effect:

postgres=# SELECT DATNAAM FROM PG_DATABASE WHERE OOID = 12917;
datname
----------
postgres
(1 row)

The next version will be able to fix permissions problems and override
errors automatically as follows, though that is proving trickier to
get working. Example:

postgres=# SUDO DROP TABLE PG_DATABASS;
NO CARRIER

--
Thomas Munro
https://enterprisedb.com

Attachments:

0001-Add-do-what-I-mean-mode-to-psql.patchapplication/octet-stream; name=0001-Add-do-what-I-mean-mode-to-psql.patchDownload
From d45cce921b81893f307f1e1b4feee7d3402a0ce1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 1 Apr 2019 09:40:36 +1300
Subject: [PATCH] Add do-what-I-mean mode to psql.

---
 src/bin/psql/dwim-mode.el                | 11 +++++++
 src/include/lib/emacs_lisp_interpreter.h | 40 ++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 src/bin/psql/dwim-mode.el
 create mode 100644 src/include/lib/emacs_lisp_interpreter.h

diff --git a/src/bin/psql/dwim-mode.el b/src/bin/psql/dwim-mode.el
new file mode 100644
index 0000000000..637dabaf1e
--- /dev/null
+++ b/src/bin/psql/dwim-mode.el
@@ -0,0 +1,11 @@
+(defun do-what-i-mean (command)
+               ,-.-,-,
+             _/ / / /       /)
+           ,'        `.   ,'')
+         _/(@) `.      `./ ,')
+        (____,`  \:`-.   \ ,')
+         (_      /::::}  / `.)
+          \    ,' :,-' ,)\ `.)
+           `.        ,')  `..)
+             \-....-'\      \)  hjw
+              `-`-`-`-`                )
diff --git a/src/include/lib/emacs_lisp_interpreter.h b/src/include/lib/emacs_lisp_interpreter.h
new file mode 100644
index 0000000000..54247e9ce4
--- /dev/null
+++ b/src/include/lib/emacs_lisp_interpreter.h
@@ -0,0 +1,40 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#define evalquote[fn;x] = apply[fn;x;NIL]
+
+#define apply[fn;x;a] = \
+     [atom[fn] -> [eq[fn;CAR] -> caar[x]; \
+                  eq[fn;CDR] -> cdar[x]; \
+                  eq[fn;CONS] -> cons[car[x];cadr[x]]; \
+                  eq[fn;ATOM] -> atom[car[x]]; \
+                  eq[fn;EQ] -> eq[car[x];cadr[x]]; \
+                  T -> apply[eval[fn;a];x;a]]; \
+     eq[car[fn];LAMBDA] -> eval[caddr[fn];pairlis[cadr[fn];x;a]]; \
+     eq[car[fn];LABEL] -> apply[caddr[fn];x;cons[cons[cadr[fn]; \
+                               caddr[fn]];a]]]
+
+#define eval[e;a] = [atom[e] -> cdr[assoc[e;a]]; \
+     atom[car[e]] -> \
+      [eq[car[e],QUOTE] -> cadr[e]; \
+      eq[car[e];COND] -> evcon[cdr[e];a]; \
+      T -> apply[car[e];evlis[cdr[e];a];a]]; \
+      T -> apply[car[e];evlis[cdr[e];a];a]]
+
+#define evcon[c;a] = [eval[caar[c];a] -> eval[cadar[c];a]; \
+      T -> evcon[cdr[c];a]]
+
+#define evlis[m;a] = [null[m] -> NIL; \
+      T -> cons[eval[car[m];a];evlis[cdr[m];a]]]
-- 
2.21.0

#2Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#1)
Re: DWIM mode for psql

On 2019-04-01 09:52:34 +1300, Thomas Munro wrote:

+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.

Indentation bug. You really need to work a bit more careful.

#3Corey Huinker
corey.huinker@gmail.com
In reply to: Andres Freund (#2)
Re: DWIM mode for psql

On Sun, Mar 31, 2019 at 5:04 PM Andres Freund <andres@anarazel.de> wrote:

On 2019-04-01 09:52:34 +1300, Thomas Munro wrote:

+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.

Indentation bug. You really need to work a bit more careful.

The patch applies cleanly, and passes "make check", but it generated an
executable called "mongodb".
Should I have run "make maintainer-clean" first?

#4Andreas Karlsson
andreas@proxel.se
In reply to: Thomas Munro (#1)
Re: DWIM mode for psql

On 3/31/19 10:52 PM, Thomas Munro wrote:> Building on the excellent work
begun by commit e529cd4ffa60, I would

like to propose a do-what-I-mean mode for psql. Please find a POC
patch attached. It works like this:

postgres=# select datnaam from pg_database where ooid = 12917;
ERROR: column "datnaam" does not exist
LINE 1: select datnaam from pg_database where ooid = 12917;
^
HINT: Perhaps you meant to reference the column "pg_database.datname".
postgres=# YES
datname
----------
postgres
(1 row)

I think it is potentially confusing that YES and NO does not look like
other psql commands. Let's pick something which is more in line with
existing commands like \y and \n.

Andreas

#5Amit Langote
amitlangote09@gmail.com
In reply to: Thomas Munro (#1)
Re: DWIM mode for psql

Hi Thomas,

Thanks for working on this.

On Mon, Apr 1, 2019 at 5:53 Thomas Munro <thomas.munro@gmail.com> wrote:

Hello,

Building on the excellent work begun by commit e529cd4ffa60, I would
like to propose a do-what-I-mean mode for psql. Please find a POC
patch attached. It works like this:

postgres=# select datnaam from pg_database where ooid = 12917;
ERROR: column "datnaam" does not exist
LINE 1: select datnaam from pg_database where ooid = 12917;
^
HINT: Perhaps you meant to reference the column "pg_database.datname".
postgres=# YES
datname
----------
postgres
(1 row)

As you can see, by "shouting" a new keyword at the computer, it will
take its own hint and run the corrected query. To avoid having to do
this in two steps, you can also shout the whole query for the same
effect:

postgres=# SELECT DATNAAM FROM PG_DATABASE WHERE OOID = 12917;
datname
----------
postgres
(1 row)

Neat.

The next version will be able to fix permissions problems and override

errors automatically as follows, though that is proving trickier to
get working. Example:

postgres=# SUDO DROP TABLE PG_DATABASS;
NO CARRIER

Have you tried rebooting the machine?

Thanks,
Amit

Show quoted text
#6legrand legrand
legrand_legrand@hotmail.com
In reply to: Andreas Karlsson (#4)
Re: DWIM mode for psql

Andreas Karlsson wrote

On 3/31/19 10:52 PM, Thomas Munro wrote:> Building on the excellent work
begun by commit e529cd4ffa60, I would

like to propose a do-what-I-mean mode for psql. Please find a POC
patch attached. It works like this:

postgres=# select datnaam from pg_database where ooid = 12917;
ERROR: column "datnaam" does not exist
LINE 1: select datnaam from pg_database where ooid = 12917;
^
HINT: Perhaps you meant to reference the column "pg_database.datname".
postgres=# YES
datname
----------
postgres
(1 row)

I think it is potentially confusing that YES and NO does not look like
other psql commands. Let's pick something which is more in line with
existing commands like \y and \n.

Andreas

+1
Regards

-)))°>

--
Sent from: http://www.postgresql-archive.org/PostgreSQL-hackers-f1928748.html