summaryrefslogtreecommitdiff
path: root/lisp/progmodes/sql.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/sql.el')
-rw-r--r--lisp/progmodes/sql.el236
1 files changed, 159 insertions, 77 deletions
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 13d4178116e..e8a95eccdd2 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -212,11 +212,11 @@
;; Michael Mauger <michael@mauger.com> -- improved product support
;; Drew Adams <drew.adams@oracle.com> -- Emacs 20 support
;; Harald Maier <maierh@myself.com> -- sql-send-string
-;; Stefan Monnier <monnier@iro.umontreal.ca> -- font-lock corrections;
+;; Stefan Monnier <monnier@iro.umontreal.ca> -- font-lock corrections;
;; code polish
;; Paul Sleigh <bat@flurf.net> -- MySQL keyword enhancement
;; Andrew Schein <andrew@andrewschein.com> -- sql-port bug
-;; Ian Bjorhovde <idbjorh@dataproxy.com> -- db2 escape newlines
+;; Ian Bjorhovde <idbjorh@dataproxy.com> -- db2 escape newlines
;; incorrectly enabled by default
;; Roman Scherer <roman.scherer@nugg.ad> -- Connection documentation
;; Mark Wilkinson <wilkinsonmr@gmail.com> -- file-local variables ignored
@@ -282,6 +282,13 @@ file. Since that is a plaintext file, this could be dangerous."
:group 'SQL
:safe 'numberp)
+(defcustom sql-default-directory nil
+ "Default directory for SQL processes."
+ :version "25.1"
+ :type '(choice (const nil) string)
+ :group 'SQL
+ :safe 'stringp)
+
;; Login parameter type
(define-widget 'sql-login-params 'lazy
@@ -498,6 +505,18 @@ file. Since that is a plaintext file, this could be dangerous."
:prompt-length 5
:syntax-alist ((?@ . "_"))
:terminator ("^go" . "go"))
+
+ (vertica
+ :name "Vertica"
+ :sqli-program sql-vertica-program
+ :sqli-options sql-vertica-options
+ :sqli-login sql-vertica-login-params
+ :sqli-comint-func sql-comint-vertica
+ :list-all ("\\d" . "\\dS")
+ :list-table "\\d %s"
+ :prompt-regexp "^\\w*=[#>] "
+ :prompt-length 5
+ :prompt-cont-regexp "^\\w*[-(][#>] ")
)
"An alist of product specific configuration settings.
@@ -1221,7 +1240,9 @@ Based on `comint-mode-map'.")
(define-key map (kbd "C-c C-r") 'sql-send-region)
(define-key map (kbd "C-c C-s") 'sql-send-string)
(define-key map (kbd "C-c C-b") 'sql-send-buffer)
+ (define-key map (kbd "C-c C-n") 'sql-send-line-and-next)
(define-key map (kbd "C-c C-i") 'sql-product-interactive)
+ (define-key map (kbd "C-c C-z") 'sql-show-sqli-buffer)
(define-key map (kbd "C-c C-l a") 'sql-list-all)
(define-key map (kbd "C-c C-l t") 'sql-list-table)
(define-key map [remap beginning-of-defun] 'sql-beginning-of-statement)
@@ -1556,8 +1577,6 @@ to add functions and PL/SQL keywords.")
;; Oracle SQL*Plus Commands
;; Only recognized in they start in column 1 and the
;; abbreviation is followed by a space or the end of line.
-
- "\\|"
(list (concat "^" (sql-regexp-abbrev "rem~ark") "\\(?:\\s-.*\\)?$")
0 'font-lock-comment-face t)
@@ -1605,6 +1624,11 @@ to add functions and PL/SQL keywords.")
0 'font-lock-doc-face t)
'("&?&\\(?:\\sw\\|\\s_\\)+[.]?" 0 font-lock-preprocessor-face t)
+ ;; Oracle PL/SQL Attributes (Declare these first to match %TYPE correctly)
+ (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b")
+"bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound"
+"rowcount" "rowtype" "type"
+)
;; Oracle Functions
(sql-font-lock-keywords-builder 'font-lock-builtin-face nil
"abs" "acos" "add_months" "appendchildxml" "ascii" "asciistr" "asin"
@@ -1634,7 +1658,7 @@ to add functions and PL/SQL keywords.")
"prediction" "prediction_bounds" "prediction_cost"
"prediction_details" "prediction_probability" "prediction_set"
"presentnnv" "presentv" "previous" "rank" "ratio_to_report" "rawtohex"
-"rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr"
+"rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr" "regexp_like"
"regexp_replace" "regexp_substr" "regr_avgx" "regr_avgy" "regr_count"
"regr_intercept" "regr_r2" "regr_slope" "regr_sxx" "regr_sxy"
"regr_syy" "remainder" "replace" "round" "rowidtochar" "rowidtonchar"
@@ -1719,7 +1743,7 @@ to add functions and PL/SQL keywords.")
"password_life_time" "password_lock_time" "password_reuse_max"
"password_reuse_time" "password_verify_function" "pctfree"
"pctincrease" "pctthreshold" "pctused" "pctversion" "percent"
-"performance" "permanent" "pfile" "physical" "pipelined" "plan"
+"performance" "permanent" "pfile" "physical" "pipelined" "pivot" "plan"
"post_transaction" "pragma" "prebuilt" "preserve" "primary" "private"
"private_sga" "privileges" "procedure" "profile" "protection" "public"
"purge" "query" "quiesce" "quota" "range" "read" "reads" "rebuild"
@@ -1742,7 +1766,7 @@ to add functions and PL/SQL keywords.")
"temporary" "test" "than" "then" "thread" "through" "time_zone"
"timeout" "to" "trace" "transaction" "trigger" "triggers" "truncate"
"trust" "type" "types" "unarchived" "under" "under_path" "undo"
-"uniform" "union" "unique" "unlimited" "unlock" "unquiesce"
+"uniform" "union" "unique" "unlimited" "unlock" "unpivot" "unquiesce"
"unrecoverable" "until" "unusable" "unused" "update" "upgrade" "usage"
"use" "using" "validate" "validation" "value" "values" "variable"
"varray" "version" "view" "wait" "when" "whenever" "where" "with"
@@ -1757,12 +1781,6 @@ to add functions and PL/SQL keywords.")
"time" "timestamp" "urowid" "varchar2" "with" "year" "zone"
)
- ;; Oracle PL/SQL Attributes
- (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b")
-"bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound"
-"rowcount" "rowtype" "type"
-)
-
;; Oracle PL/SQL Functions
(sql-font-lock-keywords-builder 'font-lock-builtin-face nil
"delete" "trim" "extend" "exists" "first" "last" "count" "limit"
@@ -3050,7 +3068,7 @@ If you call it from anywhere else, it sets the global copy of
(interactive)
(let ((default-buffer (sql-find-sqli-buffer)))
(if (null default-buffer)
- (user-error "There is no suitable SQLi buffer")
+ (sql-product-interactive)
(let ((new-buffer (read-buffer "New SQLi buffer: " default-buffer t)))
(if (null (sql-buffer-live-p new-buffer))
(user-error "Buffer %s is not a working SQLi buffer" new-buffer)
@@ -3059,21 +3077,20 @@ If you call it from anywhere else, it sets the global copy of
(run-hooks 'sql-set-sqli-hook)))))))
(defun sql-show-sqli-buffer ()
- "Show the name of current SQLi buffer.
+ "Display the current SQLi buffer.
-This is the buffer SQL strings are sent to. It is stored in the
-variable `sql-buffer'. See `sql-help' on how to create such a buffer."
+This is the buffer SQL strings are sent to.
+It is stored in the variable `sql-buffer'.
+I
+See also `sql-help' on how to create such a buffer."
(interactive)
- (if (or (null sql-buffer)
- (null (buffer-live-p (get-buffer sql-buffer))))
- (user-error "%s has no SQLi buffer set" (buffer-name (current-buffer)))
- (if (null (get-buffer-process sql-buffer))
- (user-error "Buffer %s has no process" sql-buffer)
- (user-error "Current SQLi buffer is %s" sql-buffer))))
+ (unless (and sql-buffer (buffer-live-p (get-buffer sql-buffer))
+ (get-buffer-process sql-buffer))
+ (sql-set-sqli-buffer))
+ (display-buffer sql-buffer))
(defun sql-make-alternate-buffer-name ()
"Return a string that can be used to rename a SQLi buffer.
-
This is used to set `sql-alternate-buffer-name' within
`sql-interactive-mode'.
@@ -3323,7 +3340,7 @@ to avoid deleting non-prompt output."
(setq oline (replace-match "" nil nil oline)
sql-output-newline-count (1- sql-output-newline-count)
prompt-found t)))
-
+
;; If we've found all the expected prompts, stop looking
(if (= sql-output-newline-count 0)
(setq sql-output-newline-count nil
@@ -3403,6 +3420,13 @@ to avoid deleting non-prompt output."
(interactive)
(sql-send-region (point-min) (point-max)))
+(defun sql-send-line-and-next ()
+ "Send the current line to the SQL process and go to the next line."
+ (interactive)
+ (sql-send-region (line-beginning-position 1) (line-beginning-position 2))
+ (beginning-of-line 2)
+ (while (forward-comment 1))) ; skip all comments and whitespace
+
(defun sql-send-magic-terminator (buf str terminator)
"Send TERMINATOR to buffer BUF if its not present in STR."
(let (comint-input-sender-no-newline pat term)
@@ -3480,45 +3504,51 @@ list of SQLi command strings."
(message "Executing SQL command...done"))))
(defun sql-redirect-one (sqlbuf command outbuf save-prior)
- (with-current-buffer sqlbuf
- (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
- (proc (get-buffer-process (current-buffer)))
- (comint-prompt-regexp (sql-get-product-feature sql-product
- :prompt-regexp))
- (start nil))
- (with-current-buffer buf
- (setq-local view-no-disable-on-exit t)
- (read-only-mode -1)
- (unless save-prior
- (erase-buffer))
- (goto-char (point-max))
- (unless (zerop (buffer-size))
- (insert "\n"))
- (setq start (point)))
-
- (when sql-debug-redirect
- (message ">>SQL> %S" command))
-
- ;; Run the command
- (comint-redirect-send-command-to-process command buf proc nil t)
- (while (null comint-redirect-completed)
- (accept-process-output nil 1))
-
- ;; Clean up the output results
- (with-current-buffer buf
- ;; Remove trailing whitespace
- (goto-char (point-max))
- (when (looking-back "[ \t\f\n\r]*" start)
- (delete-region (match-beginning 0) (match-end 0)))
- ;; Remove echo if there was one
- (goto-char start)
- (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
- (delete-region (match-beginning 0) (match-end 0)))
- ;; Remove Ctrl-Ms
- (goto-char start)
- (while (re-search-forward "\r+$" nil t)
- (replace-match "" t t))
- (goto-char start)))))
+ (when command
+ (with-current-buffer sqlbuf
+ (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
+ (proc (get-buffer-process (current-buffer)))
+ (comint-prompt-regexp (sql-get-product-feature sql-product
+ :prompt-regexp))
+ (start nil))
+ (with-current-buffer buf
+ (setq-local view-no-disable-on-exit t)
+ (read-only-mode -1)
+ (unless save-prior
+ (erase-buffer))
+ (goto-char (point-max))
+ (unless (zerop (buffer-size))
+ (insert "\n"))
+ (setq start (point)))
+
+ (when sql-debug-redirect
+ (message ">>SQL> %S" command))
+
+ ;; Run the command
+ (let ((inhibit-quit t)
+ comint-preoutput-filter-functions)
+ (with-local-quit
+ (comint-redirect-send-command-to-process command buf proc nil t)
+ (while (or quit-flag (null comint-redirect-completed))
+ (accept-process-output nil 1)))
+
+ (if quit-flag
+ (comint-redirect-cleanup)
+ ;; Clean up the output results
+ (with-current-buffer buf
+ ;; Remove trailing whitespace
+ (goto-char (point-max))
+ (when (looking-back "[ \t\f\n\r]*" start)
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Remove echo if there was one
+ (goto-char start)
+ (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
+ (delete-region (match-beginning 0) (match-end 0)))
+ ;; Remove Ctrl-Ms
+ (goto-char start)
+ (while (re-search-forward "\r+$" nil t)
+ (replace-match "" t t))
+ (goto-char start))))))))
(defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups)
"Execute the SQL command and return part of result.
@@ -3589,7 +3619,7 @@ buffer is popped into a view window."
(apply c sqlbuf outbuf enhanced arg nil))
(t (error "Unknown sql-execute item %s" c))))
(if (consp command) command (cons command nil)))
-
+
(setq outbuf (get-buffer outbuf))
(if (zerop (buffer-size outbuf))
(kill-buffer outbuf)
@@ -3597,7 +3627,11 @@ buffer is popped into a view window."
(get-lru-window))))
(with-current-buffer outbuf
(set-buffer-modified-p nil)
- (read-only-mode +1))
+ (setq-local revert-buffer-function
+ (lambda (_ignore-auto _noconfirm)
+ (sql-execute sqlbuf (buffer-name outbuf)
+ command enhanced arg)))
+ (special-mode))
(pop-to-buffer outbuf)
(when one-win
(shrink-window-if-larger-than-buffer)))))
@@ -3755,7 +3789,9 @@ must tell Emacs. Here's how to do that in your init file:
\(add-hook 'sql-mode-hook
(lambda ()
(modify-syntax-entry ?\\\\ \".\" sql-mode-syntax-table)))"
+ :group 'SQL
:abbrev-table sql-mode-abbrev-table
+
(if sql-mode-menu
(easy-menu-add sql-mode-menu)); XEmacs
@@ -3786,6 +3822,7 @@ must tell Emacs. Here's how to do that in your init file:
;;; SQL interactive mode
(put 'sql-interactive-mode 'mode-class 'special)
+(put 'sql-interactive-mode 'custom-mode-group 'SQL)
(defun sql-interactive-mode ()
"Major mode to use a SQL interpreter interactively.
@@ -3928,11 +3965,10 @@ you entered, right above the output it created.
;; People wanting a different history file for each
;; buffer/process/client/whatever can change separator and file-name
;; on the sql-interactive-mode-hook.
- (setq-local comint-input-ring-separator sql-input-ring-separator)
- (setq comint-input-ring-file-name sql-input-ring-file-name)
- ;; Calling the hook before calling comint-read-input-ring allows users
- ;; to set comint-input-ring-file-name in sql-interactive-mode-hook.
- (comint-read-input-ring t))
+ (let
+ ((comint-input-ring-separator sql-input-ring-separator)
+ (comint-input-ring-file-name sql-input-ring-file-name))
+ (comint-read-input-ring t)))
(defun sql-stop (process event)
"Called when the SQL process is stopped.
@@ -3942,11 +3978,15 @@ Writes the input history to a history file using
This function is a sentinel watching the SQL interpreter process.
Sentinels will always get the two parameters PROCESS and EVENT."
- (comint-write-input-ring)
- (if (and (eq (current-buffer) sql-buffer)
- (not buffer-read-only))
- (insert (format "\nProcess %s %s\n" process event))
- (message "Process %s %s" process event)))
+ (with-current-buffer (process-buffer process)
+ (let
+ ((comint-input-ring-separator sql-input-ring-separator)
+ (comint-input-ring-file-name sql-input-ring-file-name))
+ (comint-write-input-ring))
+
+ (if (not buffer-read-only)
+ (insert (format "\nProcess %s %s\n" process event))
+ (message "Process %s %s" process event))))
@@ -4164,7 +4204,9 @@ the call to \\[sql-product-interactive] with
(sql-password (default-value 'sql-password))
(sql-server (default-value 'sql-server))
(sql-database (default-value 'sql-database))
- (sql-port (default-value 'sql-port)))
+ (sql-port (default-value 'sql-port))
+ (default-directory (or sql-default-directory
+ default-directory)))
(funcall (sql-get-product-feature product :sqli-comint-func)
product
(sql-get-product-feature product :sqli-options)))
@@ -5039,6 +5081,46 @@ buffer.
+(defcustom sql-vertica-program "vsql"
+ "Command to start the Vertica client."
+ :version "25.1"
+ :type 'file
+ :group 'SQL)
+
+(defcustom sql-vertica-options '("-P" "pager=off")
+ "List of additional options for `sql-vertica-program'.
+The default value disables the internal pager."
+ :version "25.1"
+ :type '(repeat string)
+ :group 'SQL)
+
+(defcustom sql-vertica-login-params '(user password database server)
+ "List of login parameters needed to connect to Vertica."
+ :version "25.1"
+ :type 'sql-login-params
+ :group 'SQL)
+
+(defun sql-comint-vertica (product options)
+ "Create comint buffer and connect to Vertica."
+ (sql-comint product
+ (nconc
+ (and (not (string= "" sql-server))
+ (list "-h" sql-server))
+ (and (not (string= "" sql-database))
+ (list "-d" sql-database))
+ (and (not (string= "" sql-password))
+ (list "-w" sql-password))
+ (and (not (string= "" sql-user))
+ (list "-U" sql-user))
+ options)))
+
+;;;###autoload
+(defun sql-vertica (&optional buffer)
+ "Run vsql as an inferior process."
+ (interactive "P")
+ (sql-product-interactive 'vertica buffer))
+
+
(provide 'sql)
;;; sql.el ends here