Skip to content

Commit

Permalink
Add command for explaining PostgreSQL queries in a format suitable fo…
Browse files Browse the repository at this point in the history
  • Loading branch information
purcell committed Jul 16, 2017
1 parent 3476bb4 commit 6f8c52e
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions lisp/init-sql.el
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,68 @@ Fix for the above hasn't been released as of Emacs 25.2."
(add-hook 'sql-interactive-mode-hook 'sanityinc/font-lock-everything-in-sql-interactive-mode)



(defun sanityinc/sql-explain-region-as-json (beg end &optional copy)
"Explain the SQL between BEG and END in detailed JSON format.
This is suitable for pasting into tools such as
http://tatiyants.com/pev/.
When the prefix argument COPY is non-nil, do not display the
resulting JSON, but instead copy it to the kill ring.
If the region is not active, uses the current paragraph, as per
`sql-send-paragraph'.
Connection information is taken from the special sql-* variables
set in the current buffer, so you will usually want to start a
SQLi session first, or otherwise set `sql-database' etc."
(interactive "rP")
(unless (eq sql-product 'postgres)
(user-error "This command is for PostgreSQL only"))
(unless (use-region-p)
(setq beg (save-excursion
(backward-paragraph)
(point))
end (save-excursion
(forward-paragraph)
(point))))
(let ((query (buffer-substring-no-properties beg end)))
(with-current-buffer (if (sql-buffer-live-p sql-buffer)
sql-buffer
(current-buffer))
(let* ((process-environment
(append (list (concat "PGDATABASE=" sql-database)
(concat "PGHOST=" sql-server)
(concat "PGUSER=" sql-user))
process-environment))
(out-buffer (get-buffer-create "*sql-explain-json*"))
(args (list "--no-psqlrc"
"-qAt"
"-w" ; Never prompt for password
"-E"
"-c" (concat "EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) " query ";")
))
(err-file (make-temp-file "sql-explain-json")))
(with-current-buffer out-buffer
(delete-region (point-min) (point-max)))
(let ((retcode (apply 'call-process sql-postgres-program nil (list out-buffer err-file) nil args)))
(if (zerop retcode)
(with-current-buffer out-buffer
(json-mode)
(if copy
(progn
(kill-ring-save (buffer-substring-no-properties (point-min) (point-max)))
(message "EXPLAIN output copied to kill-ring."))
(display-buffer (current-buffer))))
(display-buffer (with-current-buffer (get-buffer-create "*sql-explain-errors*")
(insert-file-contents err-file nil nil nil t)
(current-buffer)))
(error "Explain failed")))))))





(after-load 'page-break-lines
(push 'sql-mode page-break-lines-modes))

Expand Down

0 comments on commit 6f8c52e

Please sign in to comment.