aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/sql.el
diff options
context:
space:
mode:
authorMichael Mauger2011-07-05 23:51:48 -0400
committerMichael Mauger2011-07-05 23:51:48 -0400
commitfbcc67e2aada556f30f6cb330c96f0094a870f2f (patch)
tree8d02734b4d32dc5a198ba41e694bc6505a765fa5 /lisp/progmodes/sql.el
parentd4eaeab175c1854421c56039c4d140ea672841a1 (diff)
downloademacs-fbcc67e2aada556f30f6cb330c96f0094a870f2f.tar.gz
emacs-fbcc67e2aada556f30f6cb330c96f0094a870f2f.zip
* progmodes/sql.el: Version 3.0
(sql-product-alist): Added product :completion-object, :completion-column, and :statement attributes. (sql-mode-menu, sql-interactive-mode-map): Fixed List entries. (sql-mode-syntax-table): Mark all punctuation. (sql-font-lock-keywords-builder): Temporarily removed fallback on ansi keywords. (sql-regexp-abbrev, sql-regexp-abbrev-list): New functions. (sql-mode-oracle-font-lock-keywords): Improved. (sql-oracle-show-reserved-words): New function for development. (sql-product-font-lock): Simplify for source code buffers. (sql-product-syntax-table, sql-product-font-lock-syntax-alist): New functions. (sql-highlight-product): Set product specific syntax table. (sql-mode-map): Added statement movement functions. (sql-ansi-statement-starters, sql-oracle-statement-starters): New variable. (sql-statement-regexp, sql-beginning-of-statement) (sql-end-of-statement, sql-signum): New functions. (sql-buffer-live-p, sql=find-sqli-buffer): Added CONNECTION parameter. (sql-show-sqli-buffer): Bug fix. (sql-interactive-mode): Store connection data as buffer local. (sql-connect): Added NEW-NAME parameter. Redesigned interaction with sql-interactive-mode. (sql-save-connection): Save buffer local settings. (sql-connection-menu-filter): Changed menu entry name. (sql-product-interactive): Bug fix. (sql-preoutput-hold): New variable. (sql-interactive-remove-continuation-prompt): Bug fixes. (sql-debug-redirect): New variable. (sql-str-literal): New function. (sql-redirect, sql-redirect-one, sql-redirect-value, sql-execute): Redesigned. (sql-oracle-save-settings, sql-oracle-restore-settings) (sql-oracle-list-all, sql-oracle-list-table): New functions. (sql-completion-object, sql-completion-column) (sql-completion-sqlbuf): New variables. (sql-build-completions-1, sql-build-completions) (sql-try-completion): New functions. (sql-read-table-name): Use them. (sql-contains-names): New buffer local variable. (sql-list-all, sql-list-table): Use it. (sql-oracle-completion-types): New variable. (sql-oracle-completion-object, sql-sqlite-completion-object) (sql-postgres-completion-object): New functions.
Diffstat (limited to 'lisp/progmodes/sql.el')
-rw-r--r--lisp/progmodes/sql.el1155
1 files changed, 900 insertions, 255 deletions
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 1da819660d2..80358e1c651 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -4,10 +4,9 @@
4 4
5;; Author: Alex Schroeder <alex@gnu.org> 5;; Author: Alex Schroeder <alex@gnu.org>
6;; Maintainer: Michael Mauger <mmaug@yahoo.com> 6;; Maintainer: Michael Mauger <mmaug@yahoo.com>
7;; Version: 2.8 7;; Version: 3.0
8;; Keywords: comm languages processes 8;; Keywords: comm languages processes
9;; URL: http://savannah.gnu.org/projects/emacs/ 9;; URL: http://savannah.gnu.org/projects/emacs/
10;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
11 10
12;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
13 12
@@ -46,7 +45,7 @@
46;; available in early versions of sql.el. This support has been 45;; available in early versions of sql.el. This support has been
47;; extended and formalized in later versions. Part of the impetus for 46;; extended and formalized in later versions. Part of the impetus for
48;; the improved support of SQL flavors was borne out of the current 47;; the improved support of SQL flavors was borne out of the current
49;; maintainer's consulting experience. In the past fifteen years, I 48;; maintainers consulting experience. In the past twenty years, I
50;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer. 49;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer.
51;; On some assignments, I have used two or more of these concurrently. 50;; On some assignments, I have used two or more of these concurrently.
52 51
@@ -130,7 +129,7 @@
130;; identifier characters. 129;; identifier characters.
131 130
132;; (sql-set-product-feature 'xyz 131;; (sql-set-product-feature 'xyz
133;; :syntax-alist ((?# . "w"))) 132;; :syntax-alist ((?# . "_")))
134 133
135;; 4) Define the interactive command interpreter for the database 134;; 4) Define the interactive command interpreter for the database
136;; product. 135;; product.
@@ -184,7 +183,7 @@
184;; (sql-set-product-feature 'xyz 183;; (sql-set-product-feature 'xyz
185;; :sqli-comint-func 'my-sql-comint-xyz) 184;; :sqli-comint-func 'my-sql-comint-xyz)
186 185
187;; 6) Define a convienence function to invoke the SQL interpreter. 186;; 6) Define a convenience function to invoke the SQL interpreter.
188 187
189;; (defun my-sql-xyz (&optional buffer) 188;; (defun my-sql-xyz (&optional buffer)
190;; "Run ixyz by XyzDB as an inferior process." 189;; "Run ixyz by XyzDB as an inferior process."
@@ -230,9 +229,18 @@
230(eval-when-compile 229(eval-when-compile
231 (require 'regexp-opt)) 230 (require 'regexp-opt))
232(require 'custom) 231(require 'custom)
232(require 'thingatpt)
233(eval-when-compile ;; needed in Emacs 19, 20 233(eval-when-compile ;; needed in Emacs 19, 20
234 (setq max-specpdl-size (max max-specpdl-size 2000))) 234 (setq max-specpdl-size (max max-specpdl-size 2000)))
235 235
236(defun sql-signum (n)
237 "Return 1, 0, or -1 to identify the sign of N."
238 (cond
239 ((not (numberp n)) nil)
240 ((< n 0) -1)
241 ((> n 0) 1)
242 (t 0)))
243
236(defvar font-lock-keyword-face) 244(defvar font-lock-keyword-face)
237(defvar font-lock-set-defaults) 245(defvar font-lock-set-defaults)
238(defvar font-lock-string-face) 246(defvar font-lock-string-face)
@@ -327,7 +335,8 @@ Customizing your password will store it in your ~/.emacs file."
327(defvar sql-product-alist 335(defvar sql-product-alist
328 '((ansi 336 '((ansi
329 :name "ANSI" 337 :name "ANSI"
330 :font-lock sql-mode-ansi-font-lock-keywords) 338 :font-lock sql-mode-ansi-font-lock-keywords
339 :statement sql-ansi-statement-starters)
331 340
332 (db2 341 (db2
333 :name "DB2" 342 :name "DB2"
@@ -392,7 +401,7 @@ Customizing your password will store it in your ~/.emacs file."
392 :sqli-comint-func sql-comint-ms 401 :sqli-comint-func sql-comint-ms
393 :prompt-regexp "^[0-9]*>" 402 :prompt-regexp "^[0-9]*>"
394 :prompt-length 5 403 :prompt-length 5
395 :syntax-alist ((?@ . "w")) 404 :syntax-alist ((?@ . "_"))
396 :terminator ("^go" . "go")) 405 :terminator ("^go" . "go"))
397 406
398 (mysql 407 (mysql
@@ -408,6 +417,7 @@ Customizing your password will store it in your ~/.emacs file."
408 :prompt-regexp "^mysql> " 417 :prompt-regexp "^mysql> "
409 :prompt-length 6 418 :prompt-length 6
410 :prompt-cont-regexp "^ -> " 419 :prompt-cont-regexp "^ -> "
420 :syntax-alist ((?# . "< b"))
411 :input-filter sql-remove-tabs-filter) 421 :input-filter sql-remove-tabs-filter)
412 422
413 (oracle 423 (oracle
@@ -417,11 +427,15 @@ Customizing your password will store it in your ~/.emacs file."
417 :sqli-options sql-oracle-options 427 :sqli-options sql-oracle-options
418 :sqli-login sql-oracle-login-params 428 :sqli-login sql-oracle-login-params
419 :sqli-comint-func sql-comint-oracle 429 :sqli-comint-func sql-comint-oracle
430 :list-all sql-oracle-list-all
431 :list-table sql-oracle-list-table
432 :completion-object sql-oracle-completion-object
420 :prompt-regexp "^SQL> " 433 :prompt-regexp "^SQL> "
421 :prompt-length 5 434 :prompt-length 5
422 :prompt-cont-regexp "^\\s-*\\d+> " 435 :prompt-cont-regexp "^\\s-*[[:digit:]]+ "
423 :syntax-alist ((?$ . "w") (?# . "w")) 436 :statement sql-oracle-statement-starters
424 :terminator ("\\(^/\\|;\\)" . "/") 437 :syntax-alist ((?$ . "_") (?# . "_"))
438 :terminator ("\\(^/\\|;\\)$" . "/")
425 :input-filter sql-placeholders-filter) 439 :input-filter sql-placeholders-filter)
426 440
427 (postgres 441 (postgres
@@ -434,11 +448,12 @@ Customizing your password will store it in your ~/.emacs file."
434 :sqli-comint-func sql-comint-postgres 448 :sqli-comint-func sql-comint-postgres
435 :list-all ("\\d+" . "\\dS+") 449 :list-all ("\\d+" . "\\dS+")
436 :list-table ("\\d+ %s" . "\\dS+ %s") 450 :list-table ("\\d+ %s" . "\\dS+ %s")
437 :prompt-regexp "^.*=[#>] " 451 :completion-object sql-postgres-completion-object
452 :prompt-regexp "^\\w*=[#>] "
438 :prompt-length 5 453 :prompt-length 5
439 :prompt-cont-regexp "^.*[-(][#>] " 454 :prompt-cont-regexp "^\\w*[-(][#>] "
440 :input-filter sql-remove-tabs-filter 455 :input-filter sql-remove-tabs-filter
441 :terminator ("\\(^\\s-*\\\\g\\|;\\)" . ";")) 456 :terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g"))
442 457
443 (solid 458 (solid
444 :name "Solid" 459 :name "Solid"
@@ -460,9 +475,10 @@ Customizing your password will store it in your ~/.emacs file."
460 :sqli-comint-func sql-comint-sqlite 475 :sqli-comint-func sql-comint-sqlite
461 :list-all ".tables" 476 :list-all ".tables"
462 :list-table ".schema %s" 477 :list-table ".schema %s"
478 :completion-object sql-sqlite-completion-object
463 :prompt-regexp "^sqlite> " 479 :prompt-regexp "^sqlite> "
464 :prompt-length 8 480 :prompt-length 8
465 :prompt-cont-regexp "^ ...> " 481 :prompt-cont-regexp "^ \.\.\.> "
466 :terminator ";") 482 :terminator ";")
467 483
468 (sybase 484 (sybase
@@ -474,7 +490,7 @@ Customizing your password will store it in your ~/.emacs file."
474 :sqli-comint-func sql-comint-sybase 490 :sqli-comint-func sql-comint-sybase
475 :prompt-regexp "^SQL> " 491 :prompt-regexp "^SQL> "
476 :prompt-length 5 492 :prompt-length 5
477 :syntax-alist ((?@ . "w")) 493 :syntax-alist ((?@ . "_"))
478 :terminator ("^go" . "go")) 494 :terminator ("^go" . "go"))
479 ) 495 )
480 "An alist of product specific configuration settings. 496 "An alist of product specific configuration settings.
@@ -513,10 +529,11 @@ may be any one of the following:
513 :sqli-comint-func name of a function which accepts no 529 :sqli-comint-func name of a function which accepts no
514 parameters that will use the values of 530 parameters that will use the values of
515 `sql-user', `sql-password', 531 `sql-user', `sql-password',
516 `sql-database' and `sql-server' to open a 532 `sql-database', `sql-server' and
517 comint buffer and connect to the 533 `sql-port' to open a comint buffer and
518 database. Do product specific 534 connect to the database. Do product
519 configuration of comint in this function. 535 specific configuration of comint in this
536 function.
520 537
521 :list-all Command string or function which produces 538 :list-all Command string or function which produces
522 a listing of all objects in the database. 539 a listing of all objects in the database.
@@ -535,6 +552,20 @@ may be any one of the following:
535 produces the standard list and the cdr 552 produces the standard list and the cdr
536 produces an enhanced list. 553 produces an enhanced list.
537 554
555 :completion-object A function that returns a list of
556 objects. Called with a single
557 parameter--if nil then list objects
558 accessible in the current schema, if
559 not-nil it is the name of a schema whose
560 objects should be listed.
561
562 :completion-column A function that returns a list of
563 columns. Called with a single
564 parameter--if nil then list objects
565 accessible in the current schema, if
566 not-nil it is the name of a schema whose
567 objects should be listed.
568
538 :prompt-regexp regular expression string that matches 569 :prompt-regexp regular expression string that matches
539 the prompt issued by the product 570 the prompt issued by the product
540 interpreter. 571 interpreter.
@@ -555,6 +586,9 @@ may be any one of the following:
555 filtered string. May also be a list of 586 filtered string. May also be a list of
556 such functions. 587 such functions.
557 588
589 :statement name of a variable containing a regexp that
590 matches the beginning of SQL statements.
591
558 :terminator the terminator to be sent after a 592 :terminator the terminator to be sent after a
559 `sql-send-string', `sql-send-region', 593 `sql-send-string', `sql-send-region',
560 `sql-send-paragraph' and 594 `sql-send-paragraph' and
@@ -574,7 +608,7 @@ using `sql-get-product-feature' to lookup the product specific
574settings.") 608settings.")
575 609
576(defvar sql-indirect-features 610(defvar sql-indirect-features
577 '(:font-lock :sqli-program :sqli-options :sqli-login)) 611 '(:font-lock :sqli-program :sqli-options :sqli-login :statement))
578 612
579(defcustom sql-connection-alist nil 613(defcustom sql-connection-alist nil
580 "An alist of connection parameters for interacting with a SQL 614 "An alist of connection parameters for interacting with a SQL
@@ -683,6 +717,13 @@ it automatically."
683 :version "22.2" 717 :version "22.2"
684 :group 'SQL) 718 :group 'SQL)
685 719
720(defvar sql-contains-names nil
721 "When non-nil, the current buffer contains database names.
722
723Globally should be set to nil; it will be non-nil in `sql-mode',
724`sql-interactive-mode' and list all buffers.")
725
726
686(defcustom sql-pop-to-buffer-after-send-region nil 727(defcustom sql-pop-to-buffer-after-send-region nil
687 "When non-nil, pop to the buffer SQL statements are sent to. 728 "When non-nil, pop to the buffer SQL statements are sent to.
688 729
@@ -770,6 +811,19 @@ is changed."
770 :type 'hook 811 :type 'hook
771 :group 'SQL) 812 :group 'SQL)
772 813
814;; Customization for ANSI
815
816(defcustom sql-ansi-statement-starters (regexp-opt '(
817 "create" "alter" "drop"
818 "select" "insert" "update" "delete" "merge"
819 "grant" "revoke"
820))
821 "Regexp of keywords that start SQL commands
822
823All products share this list; products should define a regexp to
824identify additional keywords in a variable defined by
825the :statement feature.")
826
773;; Customization for Oracle 827;; Customization for Oracle
774 828
775(defcustom sql-oracle-program "sqlplus" 829(defcustom sql-oracle-program "sqlplus"
@@ -795,18 +849,22 @@ You will find the file in your Orant\\bin directory."
795 :version "24.1" 849 :version "24.1"
796 :group 'SQL) 850 :group 'SQL)
797 851
852(defcustom sql-oracle-statement-starters (regexp-opt '("declare" "begin" "with"))
853 "Additional statement starting keywords in Oracle.")
854
798(defcustom sql-oracle-scan-on t 855(defcustom sql-oracle-scan-on t
799 "Non-nil if placeholders should be replaced in Oracle SQLi. 856 "Non-nil if placeholders should be replaced in Oracle SQLi.
800 857
801When non-nil, Emacs will scan text sent to sqlplus and prompt 858When non-nil, Emacs will scan text sent to sqlplus and prompt
802for replacement text for & placeholders as sqlplus does. This 859for replacement text for & placeholders as sqlplus does. This
803is needed on Windows where sqlplus output is buffered and the 860is needed on Windows where SQL*Plus output is buffered and the
804prompts are not shown until after the text is entered. 861prompts are not shown until after the text is entered.
805 862
806You will probably want to issue the following command in sqlplus 863You need to issue the following command in SQL*Plus to be safe:
807to be safe: 864
865 SET DEFINE OFF
808 866
809 SET SCAN OFF" 867In older versions of SQL*Plus, this was the SET SCAN OFF command."
810 :type 'boolean 868 :type 'boolean
811 :group 'SQL) 869 :group 'SQL)
812 870
@@ -833,7 +891,7 @@ Starts `sql-interactive-mode' after doing some setup."
833 :version "24.1" 891 :version "24.1"
834 :group 'SQL) 892 :group 'SQL)
835 893
836;; Customization for MySql 894;; Customization for MySQL
837 895
838(defcustom sql-mysql-program "mysql" 896(defcustom sql-mysql-program "mysql"
839 "Command to start mysql by TcX. 897 "Command to start mysql by TcX.
@@ -851,7 +909,7 @@ on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
851 :group 'SQL) 909 :group 'SQL)
852 910
853(defcustom sql-mysql-login-params '(user password database server) 911(defcustom sql-mysql-login-params '(user password database server)
854 "List of login parameters needed to connect to MySql." 912 "List of login parameters needed to connect to MySQL."
855 :type 'sql-login-params 913 :type 'sql-login-params
856 :version "24.1" 914 :version "24.1"
857 :group 'SQL) 915 :group 'SQL)
@@ -1085,13 +1143,13 @@ You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
1085 1143
1086Used by `sql-rename-buffer'.") 1144Used by `sql-rename-buffer'.")
1087 1145
1088(defun sql-buffer-live-p (buffer &optional product) 1146(defun sql-buffer-live-p (buffer &optional product connection)
1089 "Returns non-nil if the process associated with buffer is live. 1147 "Returns non-nil if the process associated with buffer is live.
1090 1148
1091BUFFER can be a buffer object or a buffer name. The buffer must 1149BUFFER can be a buffer object or a buffer name. The buffer must
1092be a live buffer, have an running process attached to it, be in 1150be a live buffer, have an running process attached to it, be in
1093`sql-interactive-mode', and, if PRODUCT is specified, it's 1151`sql-interactive-mode', and, if PRODUCT or CONNECTION are
1094`sql-product' must match." 1152specified, it's `sql-product' or `sql-connection' must match."
1095 1153
1096 (when buffer 1154 (when buffer
1097 (setq buffer (get-buffer buffer)) 1155 (setq buffer (get-buffer buffer))
@@ -1102,7 +1160,9 @@ be a live buffer, have an running process attached to it, be in
1102 (with-current-buffer buffer 1160 (with-current-buffer buffer
1103 (and (derived-mode-p 'sql-interactive-mode) 1161 (and (derived-mode-p 'sql-interactive-mode)
1104 (or (not product) 1162 (or (not product)
1105 (eq product sql-product))))))) 1163 (eq product sql-product))
1164 (or (not connection)
1165 (eq connection sql-connection)))))))
1106 1166
1107;; Keymap for sql-interactive-mode. 1167;; Keymap for sql-interactive-mode.
1108 1168
@@ -1136,6 +1196,8 @@ Based on `comint-mode-map'.")
1136 (define-key map (kbd "C-c C-i") 'sql-product-interactive) 1196 (define-key map (kbd "C-c C-i") 'sql-product-interactive)
1137 (define-key map (kbd "C-c C-l a") 'sql-list-all) 1197 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1138 (define-key map (kbd "C-c C-l t") 'sql-list-table) 1198 (define-key map (kbd "C-c C-l t") 'sql-list-table)
1199 (define-key map [remap beginning-of-defun] 'sql-beginning-of-statement)
1200 (define-key map [remap end-of-defun] 'sql-end-of-statement)
1139 map) 1201 map)
1140 "Mode map used for `sql-mode'.") 1202 "Mode map used for `sql-mode'.")
1141 1203
@@ -1151,8 +1213,10 @@ Based on `comint-mode-map'.")
1151 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] 1213 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)]
1152 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] 1214 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)]
1153 "--" 1215 "--"
1154 ["List all objects" sql-list-all (sql-buffer-live-p sql-buffer)] 1216 ["List all objects" sql-list-all (and (sql-buffer-live-p sql-buffer)
1155 ["List table details" sql-list-table (sql-buffer-live-p sql-buffer)] 1217 (sql-get-product-feature sql-product :list-all))]
1218 ["List table details" sql-list-table (and (sql-buffer-live-p sql-buffer)
1219 (sql-get-product-feature sql-product :list-table))]
1156 "--" 1220 "--"
1157 ["Start SQLi session" sql-product-interactive 1221 ["Start SQLi session" sql-product-interactive
1158 :visible (not sql-connection-alist) 1222 :visible (not sql-connection-alist)
@@ -1194,8 +1258,8 @@ Based on `comint-mode-map'.")
1194 ["Rename Buffer" sql-rename-buffer t] 1258 ["Rename Buffer" sql-rename-buffer t]
1195 ["Save Connection" sql-save-connection (not sql-connection)] 1259 ["Save Connection" sql-save-connection (not sql-connection)]
1196 "--" 1260 "--"
1197 ["List all objects" sql-list-all t] 1261 ["List all objects" sql-list-all (sql-get-product-feature sql-product :list-all)]
1198 ["List table details" sql-list-table t])) 1262 ["List table details" sql-list-table (sql-get-product-feature sql-product :list-table)]))
1199 1263
1200;; Abbreviations -- if you want more of them, define them in your 1264;; Abbreviations -- if you want more of them, define them in your
1201;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. 1265;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
@@ -1238,8 +1302,9 @@ Based on `comint-mode-map'.")
1238 (modify-syntax-entry ?' "\"" table) 1302 (modify-syntax-entry ?' "\"" table)
1239 ;; double quotes (") don't delimit strings 1303 ;; double quotes (") don't delimit strings
1240 (modify-syntax-entry ?\" "." table) 1304 (modify-syntax-entry ?\" "." table)
1241 ;; backslash is no escape character 1305 ;; Make these all punctuation
1242 (modify-syntax-entry ?\\ "." table) 1306 (mapc (lambda (c) (modify-syntax-entry c "." table))
1307 (string-to-list "!#$%&+,.:;<=>?@\\|"))
1243 table) 1308 table)
1244 "Syntax table used in `sql-mode' and `sql-interactive-mode'.") 1309 "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
1245 1310
@@ -1298,20 +1363,45 @@ statement. The format of variable should be a valid
1298 1363
1299 ;; Remove keywords that are defined in ANSI 1364 ;; Remove keywords that are defined in ANSI
1300 (setq kwd keywords) 1365 (setq kwd keywords)
1301 (dolist (k keywords) 1366 ;; (dolist (k keywords)
1302 (catch 'next 1367 ;; (catch 'next
1303 (dolist (a sql-mode-ansi-font-lock-keywords) 1368 ;; (dolist (a sql-mode-ansi-font-lock-keywords)
1304 (when (and (eq face (cdr a)) 1369 ;; (when (and (eq face (cdr a))
1305 (eq (string-match (car a) k 0) 0) 1370 ;; (eq (string-match (car a) k 0) 0)
1306 (eq (match-end 0) (length k))) 1371 ;; (eq (match-end 0) (length k)))
1307 (setq kwd (delq k kwd)) 1372 ;; (setq kwd (delq k kwd))
1308 (throw 'next nil))))) 1373 ;; (throw 'next nil)))))
1309 1374
1310 ;; Create a properly formed font-lock-keywords item 1375 ;; Create a properly formed font-lock-keywords item
1311 (cons (concat (car bdy) 1376 (cons (concat (car bdy)
1312 (regexp-opt kwd t) 1377 (regexp-opt kwd t)
1313 (cdr bdy)) 1378 (cdr bdy))
1314 face)))) 1379 face)))
1380
1381 (defun sql-regexp-abbrev (keyword)
1382 (let ((brk (string-match "[~]" keyword))
1383 (len (length keyword))
1384 (sep "\\(?:")
1385 re i)
1386 (if (not brk)
1387 keyword
1388 (setq re (substring keyword 0 brk)
1389 i (+ 2 brk)
1390 brk (1+ brk))
1391 (while (<= i len)
1392 (setq re (concat re sep (substring keyword brk i))
1393 sep "\\|"
1394 i (1+ i)))
1395 (concat re "\\)?"))))
1396
1397 (defun sql-regexp-abbrev-list (&rest keyw-list)
1398 (let ((re nil)
1399 (sep "\\<\\(?:"))
1400 (while keyw-list
1401 (setq re (concat re sep (sql-regexp-abbrev (car keyw-list)))
1402 sep "\\|"
1403 keyw-list (cdr keyw-list)))
1404 (concat re "\\)\\>"))))
1315 1405
1316(eval-when-compile 1406(eval-when-compile
1317 (setq sql-mode-ansi-font-lock-keywords 1407 (setq sql-mode-ansi-font-lock-keywords
@@ -1346,6 +1436,7 @@ statement. The format of variable should be a valid
1346"user_defined_type_catalog" "user_defined_type_name" 1436"user_defined_type_catalog" "user_defined_type_name"
1347"user_defined_type_schema" 1437"user_defined_type_schema"
1348) 1438)
1439
1349 ;; ANSI Reserved keywords 1440 ;; ANSI Reserved keywords
1350 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1441 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1351"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all" 1442"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all"
@@ -1395,6 +1486,7 @@ statement. The format of variable should be a valid
1395"substring" "sum" "system_user" "translate" "treat" "trim" "upper" 1486"substring" "sum" "system_user" "translate" "treat" "trim" "upper"
1396"user" 1487"user"
1397) 1488)
1489
1398 ;; ANSI Data Types 1490 ;; ANSI Data Types
1399 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1491 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1400"array" "binary" "bit" "blob" "boolean" "char" "character" "clob" 1492"array" "binary" "bit" "blob" "boolean" "char" "character" "clob"
@@ -1414,86 +1506,142 @@ function `regexp-opt'. Therefore, take a look at the source before
1414you define your own `sql-mode-ansi-font-lock-keywords'. You may want 1506you define your own `sql-mode-ansi-font-lock-keywords'. You may want
1415to add functions and PL/SQL keywords.") 1507to add functions and PL/SQL keywords.")
1416 1508
1509(defun sql-oracle-show-reserved-words ()
1510 ;; This function is for use by the maintainer of SQL.EL only.
1511 (interactive)
1512 (if (or (and (not (derived-mode-p 'sql-mode))
1513 (not (derived-mode-p 'sql-interactive-mode)))
1514 (not sql-buffer)
1515 (not (eq sql-product 'oracle)))
1516 (error "Not an Oracle buffer")
1517
1518 (let ((b "*RESERVED WORDS*"))
1519 (sql-execute sql-buffer b
1520 (concat "SELECT "
1521 " keyword "
1522 ", reserved AS \"Res\" "
1523 ", res_type AS \"Type\" "
1524 ", res_attr AS \"Attr\" "
1525 ", res_semi AS \"Semi\" "
1526 ", duplicate AS \"Dup\" "
1527 "FROM V$RESERVED_WORDS "
1528 "WHERE length > 1 "
1529 "AND SUBSTR(keyword, 1, 1) BETWEEN 'A' AND 'Z' "
1530 "ORDER BY 2 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC, 1;")
1531 nil nil)
1532 (with-current-buffer b
1533 (set (make-local-variable 'sql-product) 'oracle)
1534 (sql-product-font-lock t nil)
1535 (font-lock-mode +1)))))
1536
1417(defvar sql-mode-oracle-font-lock-keywords 1537(defvar sql-mode-oracle-font-lock-keywords
1418 (eval-when-compile 1538 (eval-when-compile
1419 (list 1539 (list
1420 ;; Oracle SQL*Plus Commands 1540 ;; Oracle SQL*Plus Commands
1421 (cons 1541 ;; Only recognized in they start in column 1 and the
1422 (concat 1542 ;; abbreviation is followed by a space or the end of line.
1423 "^\\s-*\\(?:\\(?:" (regexp-opt '(
1424"@" "@@" "accept" "append" "archive" "attribute" "break"
1425"btitle" "change" "clear" "column" "connect" "copy" "define"
1426"del" "describe" "disconnect" "edit" "execute" "exit" "get" "help"
1427"host" "input" "list" "password" "pause" "print" "prompt" "recover"
1428"remark" "repfooter" "repheader" "run" "save" "show" "shutdown"
1429"spool" "start" "startup" "store" "timing" "ttitle" "undefine"
1430"variable" "whenever"
1431) t)
1432 1543
1433 "\\)\\|" 1544 "\\|"
1434 "\\(?:compute\\s-+\\(?:avg\\|cou\\|min\\|max\\|num\\|sum\\|std\\|var\\)\\)\\|" 1545 (list (concat "^" (sql-regexp-abbrev "rem~ark") "\\(?:\\s-.*\\)?$")
1435 "\\(?:set\\s-+\\(" 1546 0 'font-lock-comment-face t)
1436 1547
1437 (regexp-opt 1548 (list
1438 '("appi" "appinfo" "array" "arraysize" "auto" "autocommit" 1549 (concat
1439 "autop" "autoprint" "autorecovery" "autot" "autotrace" "blo" 1550 "^\\(?:"
1440 "blockterminator" "buffer" "closecursor" "cmds" "cmdsep" 1551 (sql-regexp-abbrev-list
1441 "colsep" "com" "compatibility" "con" "concat" "constraint" 1552 "[@]\\{1,2\\}" "acc~ept" "a~ppend" "archive" "attribute"
1442 "constraints" "copyc" "copycommit" "copytypecheck" "database" 1553 "bre~ak" "bti~tle" "c~hange" "cl~ear" "col~umn" "conn~ect"
1443 "def" "define" "document" "echo" "editf" "editfile" "emb" 1554 "copy" "def~ine" "del" "desc~ribe" "disc~onnect" "ed~it"
1444 "embedded" "esc" "escape" "feed" "feedback" "flagger" "flu" 1555 "exec~ute" "exit" "get" "help" "ho~st" "[$]" "i~nput" "l~ist"
1445 "flush" "hea" "heading" "heads" "headsep" "instance" "lin" 1556 "passw~ord" "pau~se" "pri~nt" "pro~mpt" "quit" "recover"
1446 "linesize" "lobof" "loboffset" "logsource" "long" "longc" 1557 "repf~ooter" "reph~eader" "r~un" "sav~e" "sho~w" "shutdown"
1447 "longchunksize" "maxdata" "newp" "newpage" "null" "num" 1558 "spo~ol" "sta~rt" "startup" "store" "tim~ing" "tti~tle"
1448 "numf" "numformat" "numwidth" "pages" "pagesize" "pau" 1559 "undef~ine" "var~iable" "whenever")
1449 "pause" "recsep" "recsepchar" "role" "scan" "serveroutput" 1560 "\\|"
1450 "shift" "shiftinout" "show" "showmode" "space" "sqlbl" 1561 (concat "\\(?:"
1451 "sqlblanklines" "sqlc" "sqlcase" "sqlco" "sqlcontinue" "sqln" 1562 (sql-regexp-abbrev "comp~ute")
1452 "sqlnumber" "sqlp" "sqlpluscompat" "sqlpluscompatibility" 1563 "\\s-+"
1453 "sqlpre" "sqlprefix" "sqlprompt" "sqlt" "sqlterminator" 1564 (sql-regexp-abbrev-list
1454 "statement_id" "suf" "suffix" "tab" "term" "termout" "ti" 1565 "avg" "cou~nt" "min~imum" "max~imum" "num~ber" "sum"
1455 "time" "timi" "timing" "transaction" "trim" "trimout" "trims" 1566 "std" "var~iance")
1456 "trimspool" "truncate" "und" "underline" "ver" "verify" "wra" 1567 "\\)")
1457 "wrap")) "\\)\\)" 1568 "\\|"
1458 1569 (concat "\\(?:set\\s-+"
1459 "\\)\\b.*" 1570 (sql-regexp-abbrev-list
1460 ) 1571 "appi~nfo" "array~size" "auto~commit" "autop~rint"
1461 'font-lock-doc-face) 1572 "autorecovery" "autot~race" "blo~ckterminator"
1462 '("^\\s-*rem\\(?:ark\\)?\\>.*" . font-lock-comment-face) 1573 "cmds~ep" "colsep" "com~patibility" "con~cat"
1574 "copyc~ommit" "copytypecheck" "def~ine" "describe"
1575 "echo" "editf~ile" "emb~edded" "esc~ape" "feed~back"
1576 "flagger" "flu~sh" "hea~ding" "heads~ep" "instance"
1577 "lin~esize" "lobof~fset" "long" "longc~hunksize"
1578 "mark~up" "newp~age" "null" "numf~ormat" "num~width"
1579 "pages~ize" "pau~se" "recsep" "recsepchar"
1580 "scan" "serverout~put" "shift~inout" "show~mode"
1581 "sqlbl~anklines" "sqlc~ase" "sqlco~ntinue"
1582 "sqln~umber" "sqlpluscompat~ibility" "sqlpre~fix"
1583 "sqlp~rompt" "sqlt~erminator" "suf~fix" "tab"
1584 "term~out" "ti~me" "timi~ng" "trim~out" "trims~pool"
1585 "und~erline" "ver~ify" "wra~p")
1586 "\\)")
1587
1588 "\\)\\(?:\\s-.*\\)?\\(?:[-]\n.*\\)*$")
1589 0 'font-lock-doc-face t)
1463 1590
1464 ;; Oracle Functions 1591 ;; Oracle Functions
1465 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil 1592 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
1466"abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2" 1593"abs" "acos" "add_months" "appendchildxml" "ascii" "asciistr" "asin"
1467"avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid" 1594"atan" "atan2" "avg" "bfilename" "bin_to_num" "bitand" "cardinality"
1468"chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh" 1595"cast" "ceil" "chartorowid" "chr" "cluster_id" "cluster_probability"
1469"count" "covar_pop" "covar_samp" "cume_dist" "current_date" 1596"cluster_set" "coalesce" "collect" "compose" "concat" "convert" "corr"
1470"current_timestamp" "current_user" "dbtimezone" "decode" "decompose" 1597"corr_k" "corr_s" "cos" "cosh" "count" "covar_pop" "covar_samp"
1471"dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp" 1598"cube_table" "cume_dist" "currrent_date" "currrent_timestamp" "cv"
1472"extract" "extractvalue" "first" "first_value" "floor" "following" 1599"dataobj_to_partition" "dbtimezone" "decode" "decompose" "deletexml"
1473"from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap" 1600"dense_rank" "depth" "deref" "dump" "empty_blob" "empty_clob"
1474"instr" "lag" "last" "last_day" "last_value" "lead" "least" "length" 1601"existsnode" "exp" "extract" "extractvalue" "feature_id" "feature_set"
1475"ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min" 1602"feature_value" "first" "first_value" "floor" "from_tz" "greatest"
1476"mod" "months_between" "new_time" "next_day" "nls_charset_decl_len" 1603"grouping" "grouping_id" "group_id" "hextoraw" "initcap"
1604"insertchildxml" "insertchildxmlafter" "insertchildxmlbefore"
1605"insertxmlafter" "insertxmlbefore" "instr" "instr2" "instr4" "instrb"
1606"instrc" "iteration_number" "lag" "last" "last_day" "last_value"
1607"lead" "least" "length" "length2" "length4" "lengthb" "lengthc"
1608"listagg" "ln" "lnnvl" "localtimestamp" "log" "lower" "lpad" "ltrim"
1609"make_ref" "max" "median" "min" "mod" "months_between" "nanvl" "nchr"
1610"new_time" "next_day" "nlssort" "nls_charset_decl_len"
1477"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower" 1611"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower"
1478"nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval" 1612"nls_upper" "nth_value" "ntile" "nullif" "numtodsinterval"
1479"numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank" 1613"numtoyminterval" "nvl" "nvl2" "ora_dst_affected" "ora_dst_convert"
1480"percentile_cont" "percentile_disc" "power" "preceding" "rank" 1614"ora_dst_error" "ora_hash" "path" "percentile_cont" "percentile_disc"
1481"ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_" 1615"percent_rank" "power" "powermultiset" "powermultiset_by_cardinality"
1482"regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2" 1616"prediction" "prediction_bounds" "prediction_cost"
1483"regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round" 1617"prediction_details" "prediction_probability" "prediction_set"
1484"row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim" 1618"presentnnv" "presentv" "previous" "rank" "ratio_to_report" "rawtohex"
1485"sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev" 1619"rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr"
1486"stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path" 1620"regexp_replace" "regexp_substr" "regr_avgx" "regr_avgy" "regr_count"
1487"sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" 1621"regr_intercept" "regr_r2" "regr_slope" "regr_sxx" "regr_sxy"
1488"sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh" 1622"regr_syy" "remainder" "replace" "round" "rowidtochar" "rowidtonchar"
1623"row_number" "rpad" "rtrim" "scn_to_timestamp" "sessiontimezone" "set"
1624"sign" "sin" "sinh" "soundex" "sqrt" "stats_binomial_test"
1625"stats_crosstab" "stats_f_test" "stats_ks_test" "stats_mode"
1626"stats_mw_test" "stats_one_way_anova" "stats_t_test_indep"
1627"stats_t_test_indepu" "stats_t_test_one" "stats_t_test_paired"
1628"stats_wsr_test" "stddev" "stddev_pop" "stddev_samp" "substr"
1629"substr2" "substr4" "substrb" "substrc" "sum" "sysdate" "systimestamp"
1630"sys_connect_by_path" "sys_context" "sys_dburigen" "sys_extract_utc"
1631"sys_guid" "sys_typeid" "sys_xmlagg" "sys_xmlgen" "tan" "tanh"
1632"timestamp_to_scn" "to_binary_double" "to_binary_float" "to_blob"
1489"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" 1633"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
1490"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" 1634"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
1491"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" 1635"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
1492"tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user" 1636"tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv"
1493"userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml" 1637"value" "variance" "var_pop" "var_samp" "vsize" "width_bucket"
1494"xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement" 1638"xmlagg" "xmlcast" "xmlcdata" "xmlcolattval" "xmlcomment" "xmlconcat"
1495"xmlforest" "xmlsequence" "xmltransform" 1639"xmldiff" "xmlelement" "xmlexists" "xmlforest" "xmlisvalid" "xmlparse"
1640"xmlpatch" "xmlpi" "xmlquery" "xmlroot" "xmlsequence" "xmlserialize"
1641"xmltable" "xmltransform"
1496) 1642)
1643
1644 ;; See the table V$RESERVED_WORDS
1497 ;; Oracle Keywords 1645 ;; Oracle Keywords
1498 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1646 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1499"abort" "access" "accessed" "account" "activate" "add" "admin" 1647"abort" "access" "accessed" "account" "activate" "add" "admin"
@@ -1582,52 +1730,120 @@ to add functions and PL/SQL keywords.")
1582"varray" "version" "view" "wait" "when" "whenever" "where" "with" 1730"varray" "version" "view" "wait" "when" "whenever" "where" "with"
1583"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype" 1731"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype"
1584) 1732)
1733
1585 ;; Oracle Data Types 1734 ;; Oracle Data Types
1586 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1735 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1587"bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal" 1736"bfile" "binary_double" "binary_float" "blob" "byte" "char" "charbyte"
1588"double" "float" "int" "integer" "interval" "long" "national" "nchar" 1737"clob" "date" "day" "float" "interval" "local" "long" "longraw"
1589"nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real" 1738"minute" "month" "nchar" "nclob" "number" "nvarchar2" "raw" "rowid" "second"
1590"rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar" 1739"time" "timestamp" "urowid" "varchar2" "with" "year" "zone"
1591"varchar2" "varying" "year" "zone"
1592) 1740)
1593 1741
1594 ;; Oracle PL/SQL Attributes 1742 ;; Oracle PL/SQL Attributes
1595 (sql-font-lock-keywords-builder 'font-lock-builtin-face '("" . "\\b") 1743 (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b")
1596"%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype" 1744"bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound"
1597"%type" 1745"rowcount" "rowtype" "type"
1598) 1746)
1599 1747
1600 ;; Oracle PL/SQL Functions 1748 ;; Oracle PL/SQL Functions
1601 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil 1749 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
1602"extend" "prior" 1750"delete" "trim" "extend" "exists" "first" "last" "count" "limit"
1751"prior" "next"
1752)
1753
1754 ;; Oracle PL/SQL Reserved words
1755 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1756"all" "alter" "and" "any" "as" "asc" "at" "begin" "between" "by"
1757"case" "check" "clusters" "cluster" "colauth" "columns" "compress"
1758"connect" "crash" "create" "cursor" "declare" "default" "desc"
1759"distinct" "drop" "else" "end" "exception" "exclusive" "fetch" "for"
1760"from" "function" "goto" "grant" "group" "having" "identified" "if"
1761"in" "index" "indexes" "insert" "intersect" "into" "is" "like" "lock"
1762"minus" "mode" "nocompress" "not" "nowait" "null" "of" "on" "option"
1763"or" "order" "overlaps" "procedure" "public" "resource" "revoke"
1764"select" "share" "size" "sql" "start" "subtype" "tabauth" "table"
1765"then" "to" "type" "union" "unique" "update" "values" "view" "views"
1766"when" "where" "with"
1767
1768"true" "false"
1769"raise_application_error"
1603) 1770)
1604 1771
1605 ;; Oracle PL/SQL Keywords 1772 ;; Oracle PL/SQL Keywords
1606 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1773 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1607"autonomous_transaction" "bulk" "char_base" "collect" "constant" 1774"a" "add" "agent" "aggregate" "array" "attribute" "authid" "avg"
1608"cursor" "declare" "do" "elsif" "exception_init" "execute" "exit" 1775"bfile_base" "binary" "blob_base" "block" "body" "both" "bound" "bulk"
1609"extends" "false" "fetch" "forall" "goto" "hour" "if" "interface" 1776"byte" "c" "call" "calling" "cascade" "char" "char_base" "character"
1610"loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype" 1777"charset" "charsetform" "charsetid" "clob_base" "close" "collect"
1611"separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype" 1778"comment" "commit" "committed" "compiled" "constant" "constructor"
1612"the" "timezone_abbr" "timezone_hour" "timezone_minute" 1779"context" "continue" "convert" "count" "current" "customdatum"
1613"timezone_region" "true" "varrying" "while" 1780"dangling" "data" "date" "date_base" "day" "define" "delete"
1781"deterministic" "double" "duration" "element" "elsif" "empty" "escape"
1782"except" "exceptions" "execute" "exists" "exit" "external" "final"
1783"fixed" "float" "forall" "force" "general" "hash" "heap" "hidden"
1784"hour" "immediate" "including" "indicator" "indices" "infinite"
1785"instantiable" "int" "interface" "interval" "invalidate" "isolation"
1786"java" "language" "large" "leading" "length" "level" "library" "like2"
1787"like4" "likec" "limit" "limited" "local" "long" "loop" "map" "max"
1788"maxlen" "member" "merge" "min" "minute" "mod" "modify" "month"
1789"multiset" "name" "nan" "national" "native" "nchar" "new" "nocopy"
1790"number_base" "object" "ocicoll" "ocidate" "ocidatetime" "ociduration"
1791"ociinterval" "ociloblocator" "ocinumber" "ociraw" "ociref"
1792"ocirefcursor" "ocirowid" "ocistring" "ocitype" "old" "only" "opaque"
1793"open" "operator" "oracle" "oradata" "organization" "orlany" "orlvary"
1794"others" "out" "overriding" "package" "parallel_enable" "parameter"
1795"parameters" "parent" "partition" "pascal" "pipe" "pipelined" "pragma"
1796"precision" "prior" "private" "raise" "range" "raw" "read" "record"
1797"ref" "reference" "relies_on" "rem" "remainder" "rename" "result"
1798"result_cache" "return" "returning" "reverse" "rollback" "row"
1799"sample" "save" "savepoint" "sb1" "sb2" "sb4" "second" "segment"
1800"self" "separate" "sequence" "serializable" "set" "short" "size_t"
1801"some" "sparse" "sqlcode" "sqldata" "sqlname" "sqlstate" "standard"
1802"static" "stddev" "stored" "string" "struct" "style" "submultiset"
1803"subpartition" "substitutable" "sum" "synonym" "tdo" "the" "time"
1804"timestamp" "timezone_abbr" "timezone_hour" "timezone_minute"
1805"timezone_region" "trailing" "transaction" "transactional" "trusted"
1806"ub1" "ub2" "ub4" "under" "unsigned" "untrusted" "use" "using"
1807"valist" "value" "variable" "variance" "varray" "varying" "void"
1808"while" "work" "wrapped" "write" "year" "zone"
1809;; Pragma
1810"autonomous_transaction" "exception_init" "inline"
1811"restrict_references" "serially_reusable"
1614) 1812)
1615 1813
1616 ;; Oracle PL/SQL Data Types 1814 ;; Oracle PL/SQL Data Types
1617 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1815 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1618"binary_integer" "boolean" "naturaln" "pls_integer" "positive" 1816"\"BINARY LARGE OBJECT\"" "\"CHAR LARGE OBJECT\"" "\"CHAR VARYING\""
1619"positiven" "record" "signtype" "string" 1817"\"CHARACTER LARGE OBJECT\"" "\"CHARACTER VARYING\""
1818"\"DOUBLE PRECISION\"" "\"INTERVAL DAY TO SECOND\""
1819"\"INTERVAL YEAR TO MONTH\"" "\"LONG RAW\"" "\"NATIONAL CHAR\""
1820"\"NATIONAL CHARACTER LARGE OBJECT\"" "\"NATIONAL CHARACTER\""
1821"\"NCHAR LARGE OBJECT\"" "\"NCHAR\"" "\"NCLOB\"" "\"NVARCHAR2\""
1822"\"TIME WITH TIME ZONE\"" "\"TIMESTAMP WITH LOCAL TIME ZONE\""
1823"\"TIMESTAMP WITH TIME ZONE\""
1824"bfile" "bfile_base" "binary_double" "binary_float" "binary_integer"
1825"blob" "blob_base" "boolean" "char" "character" "char_base" "clob"
1826"clob_base" "cursor" "date" "day" "dec" "decimal"
1827"dsinterval_unconstrained" "float" "int" "integer" "interval" "local"
1828"long" "mlslabel" "month" "natural" "naturaln" "nchar_cs" "number"
1829"number_base" "numeric" "pls_integer" "positive" "positiven" "raw"
1830"real" "ref" "rowid" "second" "signtype" "simple_double"
1831"simple_float" "simple_integer" "smallint" "string" "time" "timestamp"
1832"timestamp_ltz_unconstrained" "timestamp_tz_unconstrained"
1833"timestamp_unconstrained" "time_tz_unconstrained" "time_unconstrained"
1834"to" "urowid" "varchar" "varchar2" "with" "year"
1835"yminterval_unconstrained" "zone"
1620) 1836)
1621 1837
1622 ;; Oracle PL/SQL Exceptions 1838 ;; Oracle PL/SQL Exceptions
1623 (sql-font-lock-keywords-builder 'font-lock-warning-face nil 1839 (sql-font-lock-keywords-builder 'font-lock-warning-face nil
1624"access_into_null" "case_not_found" "collection_is_null" 1840"access_into_null" "case_not_found" "collection_is_null"
1625"cursor_already_open" "dup_val_on_index" "invalid_cursor" 1841"cursor_already_open" "dup_val_on_index" "invalid_cursor"
1626"invalid_number" "login_denied" "no_data_found" "not_logged_on" 1842"invalid_number" "login_denied" "no_data_found" "no_data_needed"
1627"program_error" "rowtype_mismatch" "self_is_null" "storage_error" 1843"not_logged_on" "program_error" "rowtype_mismatch" "self_is_null"
1628"subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid" 1844"storage_error" "subscript_beyond_count" "subscript_outside_limit"
1629"timeout_on_resource" "too_many_rows" "value_error" "zero_divide" 1845"sys_invalid_rowid" "timeout_on_resource" "too_many_rows"
1630"exception" "notfound" 1846"value_error" "zero_divide"
1631))) 1847)))
1632 1848
1633 "Oracle SQL keywords used by font-lock. 1849 "Oracle SQL keywords used by font-lock.
@@ -2296,10 +2512,7 @@ also be configured."
2296 2512
2297 (let 2513 (let
2298 ;; Get the product-specific syntax-alist. 2514 ;; Get the product-specific syntax-alist.
2299 ((syntax-alist 2515 ((syntax-alist (sql-product-font-lock-syntax-alist)))
2300 (append
2301 (sql-get-product-feature sql-product :syntax-alist)
2302 '((?_ . "w") (?. . "w")))))
2303 2516
2304 ;; Get the product-specific keywords. 2517 ;; Get the product-specific keywords.
2305 (set (make-local-variable 'sql-mode-font-lock-keywords) 2518 (set (make-local-variable 'sql-mode-font-lock-keywords)
@@ -2388,9 +2601,30 @@ adds a fontification pattern to fontify identifiers ending in
2388 2601
2389;;; Functions to switch highlighting 2602;;; Functions to switch highlighting
2390 2603
2604(defun sql-product-syntax-table ()
2605 (let ((table (copy-syntax-table sql-mode-syntax-table)))
2606 (mapc (lambda (entry)
2607 (modify-syntax-entry (car entry) (cdr entry) table))
2608 (sql-get-product-feature sql-product :syntax-alist))
2609 table))
2610
2611(defun sql-product-font-lock-syntax-alist ()
2612 (append
2613 ;; Change all symbol character to word characters
2614 (mapcar
2615 (lambda (entry) (if (string= (substring (cdr entry) 0 1) "_")
2616 (cons (car entry)
2617 (concat "w" (substring (cdr entry) 1)))
2618 entry))
2619 (sql-get-product-feature sql-product :syntax-alist))
2620 '((?_ . "w"))))
2621
2391(defun sql-highlight-product () 2622(defun sql-highlight-product ()
2392 "Turn on the font highlighting for the SQL product selected." 2623 "Turn on the font highlighting for the SQL product selected."
2393 (when (derived-mode-p 'sql-mode) 2624 (when (derived-mode-p 'sql-mode)
2625 ;; Enhance the syntax table for the product
2626 (set-syntax-table (sql-product-syntax-table))
2627
2394 ;; Setup font-lock 2628 ;; Setup font-lock
2395 (sql-product-font-lock nil t) 2629 (sql-product-font-lock nil t)
2396 2630
@@ -2418,11 +2652,77 @@ adds a fontification pattern to fontify identifiers ending in
2418 ;; comint-line-beginning-position is defined in Emacs 21 2652 ;; comint-line-beginning-position is defined in Emacs 21
2419 (defun comint-line-beginning-position () 2653 (defun comint-line-beginning-position ()
2420 "Return the buffer position of the beginning of the line, after any prompt. 2654 "Return the buffer position of the beginning of the line, after any prompt.
2421The prompt is assumed to be any text at the beginning of the line matching 2655The prompt is assumed to be any text at the beginning of the line
2422the regular expression `comint-prompt-regexp', a buffer local variable." 2656matching the regular expression `comint-prompt-regexp', a buffer
2657local variable."
2423 (save-excursion (comint-bol nil) (point)))) 2658 (save-excursion (comint-bol nil) (point))))
2424 2659
2425 2660;;; Motion Functions
2661
2662(defun sql-statement-regexp (prod)
2663 (let* ((ansi-stmt (sql-get-product-feature 'ansi :statement))
2664 (prod-stmt (sql-get-product-feature prod :statement)))
2665 (concat "^\\<"
2666 (if prod-stmt
2667 ansi-stmt
2668 (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)"))
2669 "\\>")))
2670
2671(defun sql-beginning-of-statement (arg)
2672 "Moves the cursor to the beginning of the current SQL statement."
2673 (interactive "p")
2674
2675 (let ((here (point))
2676 (regexp (sql-statement-regexp sql-product))
2677 last next)
2678
2679 ;; Go to the end of the statement before the start we desire
2680 (setq last (or (sql-end-of-statement (- arg))
2681 (point-min)))
2682 ;; And find the end after that
2683 (setq next (or (sql-end-of-statement 1)
2684 (point-max)))
2685
2686 ;; Our start must be between them
2687 (goto-char last)
2688 ;; Find an beginning-of-stmt that's not in a comment
2689 (while (and (re-search-forward regexp next t 1)
2690 (nth 7 (syntax-ppss)))
2691 (goto-char (match-end 0)))
2692 (goto-char
2693 (if (match-data)
2694 (match-beginning 0)
2695 last))
2696 (beginning-of-line)
2697 ;; If we didn't move, try again
2698 (when (= here (point))
2699 (sql-beginning-of-statement (* 2 (sql-signum arg))))))
2700
2701(defun sql-end-of-statement (arg)
2702 "Moves the cursor to the end of the current SQL statement."
2703 (interactive "p")
2704 (let ((term (sql-get-product-feature sql-product :terminator))
2705 (re-search (if (> 0 arg) 're-search-backward 're-search-forward))
2706 (here (point))
2707 (n 0))
2708 (when (consp term)
2709 (setq term (car term)))
2710 ;; Iterate until we've moved the desired number of stmt ends
2711 (while (not (= (sql-signum arg) 0))
2712 ;; if we're looking at the terminator, jump by 2
2713 (if (or (and (> 0 arg) (looking-back term))
2714 (and (< 0 arg) (looking-at term)))
2715 (setq n 2)
2716 (setq n 1))
2717 ;; If we found another end-of-stmt
2718 (if (not (apply re-search term nil t n nil))
2719 (setq arg 0)
2720 ;; count it if we're not in a comment
2721 (unless (nth 7 (syntax-ppss))
2722 (setq arg (- arg (sql-signum arg))))))
2723 (goto-char (if (match-data)
2724 (match-end 0)
2725 here))))
2426 2726
2427;;; Small functions 2727;;; Small functions
2428 2728
@@ -2456,7 +2756,7 @@ the regular expression `comint-prompt-regexp', a buffer local variable."
2456(defun sql-help-list-products (indent freep) 2756(defun sql-help-list-products (indent freep)
2457 "Generate listing of products available for use under SQLi. 2757 "Generate listing of products available for use under SQLi.
2458 2758
2459List products with :free-softare attribute set to FREEP. Indent 2759List products with :free-software attribute set to FREEP. Indent
2460each line with INDENT." 2760each line with INDENT."
2461 2761
2462 (let (sqli-func doc) 2762 (let (sqli-func doc)
@@ -2649,7 +2949,7 @@ function like this: (sql-get-login 'user 'password 'database)."
2649 nil (append '(:number t) plist))))))) 2949 nil (append '(:number t) plist)))))))
2650 what)) 2950 what))
2651 2951
2652(defun sql-find-sqli-buffer (&optional product) 2952(defun sql-find-sqli-buffer (&optional product connection)
2653 "Returns the name of the current default SQLi buffer or nil. 2953 "Returns the name of the current default SQLi buffer or nil.
2654In order to qualify, the SQLi buffer must be alive, be in 2954In order to qualify, the SQLi buffer must be alive, be in
2655`sql-interactive-mode' and have a process." 2955`sql-interactive-mode' and have a process."
@@ -2657,16 +2957,16 @@ In order to qualify, the SQLi buffer must be alive, be in
2657 (prod (or product sql-product))) 2957 (prod (or product sql-product)))
2658 (or 2958 (or
2659 ;; Current sql-buffer, if there is one. 2959 ;; Current sql-buffer, if there is one.
2660 (and (sql-buffer-live-p buf prod) 2960 (and (sql-buffer-live-p buf prod connection)
2661 buf) 2961 buf)
2662 ;; Global sql-buffer 2962 ;; Global sql-buffer
2663 (and (setq buf (default-value 'sql-buffer)) 2963 (and (setq buf (default-value 'sql-buffer))
2664 (sql-buffer-live-p buf prod) 2964 (sql-buffer-live-p buf prod connection)
2665 buf) 2965 buf)
2666 ;; Look thru each buffer 2966 ;; Look thru each buffer
2667 (car (apply 'append 2967 (car (apply 'append
2668 (mapcar (lambda (b) 2968 (mapcar (lambda (b)
2669 (and (sql-buffer-live-p b prod) 2969 (and (sql-buffer-live-p b prod connection)
2670 (list (buffer-name b)))) 2970 (list (buffer-name b))))
2671 (buffer-list))))))) 2971 (buffer-list)))))))
2672 2972
@@ -2722,7 +3022,8 @@ If you call it from anywhere else, it sets the global copy of
2722This is the buffer SQL strings are sent to. It is stored in the 3022This is the buffer SQL strings are sent to. It is stored in the
2723variable `sql-buffer'. See `sql-help' on how to create such a buffer." 3023variable `sql-buffer'. See `sql-help' on how to create such a buffer."
2724 (interactive) 3024 (interactive)
2725 (if (null (buffer-live-p (get-buffer sql-buffer))) 3025 (if (or (null sql-buffer)
3026 (null (buffer-live-p (get-buffer sql-buffer))))
2726 (message "%s has no SQLi buffer set." (buffer-name (current-buffer))) 3027 (message "%s has no SQLi buffer set." (buffer-name (current-buffer)))
2727 (if (null (get-buffer-process sql-buffer)) 3028 (if (null (get-buffer-process sql-buffer))
2728 (message "Buffer %s has no process." sql-buffer) 3029 (message "Buffer %s has no process." sql-buffer)
@@ -2932,37 +3233,58 @@ Allows the suppression of continuation prompts.")
2932 3233
2933;;; Strip out continuation prompts 3234;;; Strip out continuation prompts
2934 3235
3236(defvar sql-preoutput-hold nil)
3237
2935(defun sql-interactive-remove-continuation-prompt (oline) 3238(defun sql-interactive-remove-continuation-prompt (oline)
2936 "Strip out continuation prompts out of the OLINE. 3239 "Strip out continuation prompts out of the OLINE.
2937 3240
2938Added to the `comint-preoutput-filter-functions' hook in a SQL 3241Added to the `comint-preoutput-filter-functions' hook in a SQL
2939interactive buffer. If `sql-outut-newline-count' is greater than 3242interactive buffer. If `sql-output-newline-count' is greater than
2940zero, then an output line matching the continuation prompt is filtered 3243zero, then an output line matching the continuation prompt is filtered
2941out. If the count is one, then the prompt is replaced with a newline 3244out. If the count is zero, then a newline is inserted into the output
2942to force the output from the query to appear on a new line." 3245to force the output from the query to appear on a new line.
2943 (if (and sql-prompt-cont-regexp 3246
2944 sql-output-newline-count 3247The complication to this filter is that the continuation prompts
2945 (numberp sql-output-newline-count) 3248may arrive in multiple chunks. If they do, then the function
2946 (>= sql-output-newline-count 1)) 3249saves any unfiltered output in a buffer and prepends that buffer
2947 (progn 3250to the next chunk to properly match the broken-up prompt.
2948 (while (and oline 3251
2949 sql-output-newline-count 3252If the filter gets confused, it should reset and stop filtering
2950 (> sql-output-newline-count 0) 3253to avoid deleting non-prompt output."
2951 (string-match sql-prompt-cont-regexp oline)) 3254
2952 3255 (let (did-filter)
2953 (setq oline 3256 (setq oline (concat (or sql-preoutput-hold "") oline)
2954 (replace-match (if (and 3257 sql-preoutput-hold nil)
2955 (= 1 sql-output-newline-count) 3258
2956 sql-output-by-send) 3259 (if (and comint-prompt-regexp
2957 "\n" "") 3260 (integerp sql-output-newline-count)
2958 nil nil oline) 3261 (>= sql-output-newline-count 1))
2959 sql-output-newline-count 3262 (progn
2960 (1- sql-output-newline-count))) 3263 (while (and (not (string= oline ""))
2961 (if (= sql-output-newline-count 0) 3264 (> sql-output-newline-count 0)
2962 (setq sql-output-newline-count nil)) 3265 (string-match comint-prompt-regexp oline)
2963 (setq sql-output-by-send nil)) 3266 (= (match-beginning 0) 0))
2964 (setq sql-output-newline-count nil)) 3267
2965 oline) 3268 (setq oline (replace-match "" nil nil oline)
3269 sql-output-newline-count (1- sql-output-newline-count)
3270 did-filter t))
3271
3272 (if (= sql-output-newline-count 0)
3273 (setq sql-output-newline-count nil
3274 oline (concat "\n" oline)
3275 sql-output-by-send nil)
3276
3277 (setq sql-preoutput-hold oline
3278 oline ""))
3279
3280 (unless did-filter
3281 (setq oline (or sql-preoutput-hold "")
3282 sql-preoutput-hold nil
3283 sql-output-newline-count nil)))
3284
3285 (setq sql-output-newline-count nil))
3286
3287 oline))
2966 3288
2967;;; Sending the region to the SQLi buffer. 3289;;; Sending the region to the SQLi buffer.
2968 3290
@@ -3066,16 +3388,35 @@ If given the optional parameter VALUE, sets
3066 3388
3067;;; Redirect output functions 3389;;; Redirect output functions
3068 3390
3069(defun sql-redirect (command combuf &optional outbuf save-prior) 3391(defvar sql-debug-redirect nil
3392 "If non-nil, display messages related to the use of redirection.")
3393
3394(defun sql-str-literal (s)
3395 (concat "'" (replace-regexp-in-string "[']" "''" s) "'"))
3396
3397(defun sql-redirect (sqlbuf command &optional outbuf save-prior)
3070 "Execute the SQL command and send output to OUTBUF. 3398 "Execute the SQL command and send output to OUTBUF.
3071 3399
3072COMBUF must be an active SQL interactive buffer. OUTBUF may be 3400SQLBUF must be an active SQL interactive buffer. OUTBUF may be
3073an existing buffer, or the name of a non-existing buffer. If 3401an existing buffer, or the name of a non-existing buffer. If
3074omitted the output is sent to a temporary buffer which will be 3402omitted the output is sent to a temporary buffer which will be
3075killed after the command completes. COMMAND should be a string 3403killed after the command completes. COMMAND should be a string
3076of commands accepted by the SQLi program." 3404of commands accepted by the SQLi program. COMMAND may also be a
3077 3405list of SQLi command strings."
3078 (with-current-buffer combuf 3406
3407 (let* ((visible (and outbuf
3408 (not (string= " " (substring outbuf 0 1))))))
3409 (when visible
3410 (message "Executing SQL command..."))
3411 (if (consp command)
3412 (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior))
3413 command)
3414 (sql-redirect-one sqlbuf command outbuf save-prior))
3415 (when visible
3416 (message "Executing SQL command...done"))))
3417
3418(defun sql-redirect-one (sqlbuf command outbuf save-prior)
3419 (with-current-buffer sqlbuf
3079 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*"))) 3420 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
3080 (proc (get-buffer-process (current-buffer))) 3421 (proc (get-buffer-process (current-buffer)))
3081 (comint-prompt-regexp (sql-get-product-feature sql-product 3422 (comint-prompt-regexp (sql-get-product-feature sql-product
@@ -3090,12 +3431,13 @@ of commands accepted by the SQLi program."
3090 (insert "\n")) 3431 (insert "\n"))
3091 (setq start (point))) 3432 (setq start (point)))
3092 3433
3434 (when sql-debug-redirect
3435 (message ">>SQL> %S" command))
3436
3093 ;; Run the command 3437 ;; Run the command
3094 (message "Executing SQL command...")
3095 (comint-redirect-send-command-to-process command buf proc nil t) 3438 (comint-redirect-send-command-to-process command buf proc nil t)
3096 (while (null comint-redirect-completed) 3439 (while (null comint-redirect-completed)
3097 (accept-process-output nil 1)) 3440 (accept-process-output nil 1))
3098 (message "Executing SQL command...done")
3099 3441
3100 ;; Clean up the output results 3442 ;; Clean up the output results
3101 (with-current-buffer buf 3443 (with-current-buffer buf
@@ -3107,12 +3449,16 @@ of commands accepted by the SQLi program."
3107 (goto-char start) 3449 (goto-char start)
3108 (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) 3450 (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
3109 (delete-region (match-beginning 0) (match-end 0))) 3451 (delete-region (match-beginning 0) (match-end 0)))
3452 ;; Remove Ctrl-Ms
3453 (goto-char start)
3454 (while (re-search-forward "\r+$" nil t)
3455 (replace-match "" t t))
3110 (goto-char start))))) 3456 (goto-char start)))))
3111 3457
3112(defun sql-redirect-value (command combuf regexp &optional regexp-groups) 3458(defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups)
3113 "Execute the SQL command and return part of result. 3459 "Execute the SQL command and return part of result.
3114 3460
3115COMBUF must be an active SQL interactive buffer. COMMAND should 3461SQLBUF must be an active SQL interactive buffer. COMMAND should
3116be a string of commands accepted by the SQLi program. From the 3462be a string of commands accepted by the SQLi program. From the
3117output, the REGEXP is repeatedly matched and the list of 3463output, the REGEXP is repeatedly matched and the list of
3118REGEXP-GROUPS submatches is returned. This behaves much like 3464REGEXP-GROUPS submatches is returned. This behaves much like
@@ -3122,18 +3468,19 @@ for each match."
3122 3468
3123 (let ((outbuf " *SQL-Redirect-values*") 3469 (let ((outbuf " *SQL-Redirect-values*")
3124 (results nil)) 3470 (results nil))
3125 (sql-redirect command combuf outbuf nil) 3471 (sql-redirect sqlbuf command outbuf nil)
3126 (with-current-buffer outbuf 3472 (with-current-buffer outbuf
3127 (while (re-search-forward regexp nil t) 3473 (while (re-search-forward regexp nil t)
3128 (push 3474 (push
3129 (cond 3475 (cond
3130 ;; no groups-return all of them 3476 ;; no groups-return all of them
3131 ((null regexp-groups) 3477 ((null regexp-groups)
3132 (let ((i 1) 3478 (let ((i (/ (length (match-data)) 2))
3133 (r nil)) 3479 (r nil))
3134 (while (match-beginning i) 3480 (while (> i 0)
3481 (setq i (1- i))
3135 (push (match-string i) r)) 3482 (push (match-string i) r))
3136 (nreverse r))) 3483 r))
3137 ;; one group specified 3484 ;; one group specified
3138 ((numberp regexp-groups) 3485 ((numberp regexp-groups)
3139 (match-string regexp-groups)) 3486 (match-string regexp-groups))
@@ -3152,10 +3499,14 @@ for each match."
3152 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" 3499 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
3153 regexp-groups))) 3500 regexp-groups)))
3154 results))) 3501 results)))
3155 (nreverse results)))
3156 3502
3157(defun sql-execute (sqlbuf outbuf command arg) 3503 (when sql-debug-redirect
3158 "Executes a command in a SQL interacive buffer and captures the output. 3504 (message ">>SQL> = %S" (reverse results)))
3505
3506 (nreverse results)))
3507
3508(defun sql-execute (sqlbuf outbuf command enhanced arg)
3509 "Executes a command in a SQL interactive buffer and captures the output.
3159 3510
3160The commands are run in SQLBUF and the output saved in OUTBUF. 3511The commands are run in SQLBUF and the output saved in OUTBUF.
3161COMMAND must be a string, a function or a list of such elements. 3512COMMAND must be a string, a function or a list of such elements.
@@ -3168,9 +3519,9 @@ buffer is popped into a view window. "
3168 (lambda (c) 3519 (lambda (c)
3169 (cond 3520 (cond
3170 ((stringp c) 3521 ((stringp c)
3171 (sql-redirect (if arg (format c arg) c) sqlbuf outbuf) t) 3522 (sql-redirect sqlbuf (if arg (format c arg) c) outbuf) t)
3172 ((functionp c) 3523 ((functionp c)
3173 (apply c sqlbuf outbuf arg)) 3524 (apply c sqlbuf outbuf enhanced arg nil))
3174 (t (error "Unknown sql-execute item %s" c)))) 3525 (t (error "Unknown sql-execute item %s" c))))
3175 (if (consp command) command (cons command nil))) 3526 (if (consp command) command (cons command nil)))
3176 3527
@@ -3197,14 +3548,92 @@ buffer is popped into a view window. "
3197 (setq command (if enhanced 3548 (setq command (if enhanced
3198 (cdr command) 3549 (cdr command)
3199 (car command)))) 3550 (car command))))
3200 (sql-execute sqlbuf outbuf command arg))) 3551 (sql-execute sqlbuf outbuf command enhanced arg)))
3552
3553(defvar sql-completion-object nil
3554 "A list of database objects used for completion.
3555
3556The list is maintained in SQL interactive buffers.")
3557
3558(defvar sql-completion-column nil
3559 "A list of column names used for completion.
3560
3561The list is maintained in SQL interactive buffers.")
3562
3563(defun sql-build-completions-1 (schema completion-list feature)
3564 "Generate a list of objects in the database for use as completions."
3565 (let ((f (sql-get-product-feature sql-product feature)))
3566 (when f
3567 (set completion-list
3568 (let (cl)
3569 (dolist (e (append (symbol-value completion-list)
3570 (apply f (current-buffer) (cons schema nil)))
3571 cl)
3572 (unless (member e cl) (setq cl (cons e cl))))
3573 (sort cl (function string<)))))))
3574
3575(defun sql-build-completions (schema)
3576 "Generate a list of names in the database for use as completions."
3577 (sql-build-completions-1 schema 'sql-completion-object :completion-object)
3578 (sql-build-completions-1 schema 'sql-completion-column :completion-column))
3579
3580(defvar sql-completion-sqlbuf nil)
3581
3582(defun sql-try-completion (string collection &optional predicate)
3583 (when sql-completion-sqlbuf
3584 (with-current-buffer sql-completion-sqlbuf
3585 (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string)
3586 (downcase (match-string 1 string)))))
3587
3588 ;; If we haven't loaded any object name yet, load local schema
3589 (unless sql-completion-object
3590 (sql-build-completions nil))
3591
3592 ;; If they want another schema, load it if we haven't yet
3593 (when schema
3594 (let ((schema-dot (concat schema "."))
3595 (schema-len (1+ (length schema)))
3596 (names sql-completion-object)
3597 has-schema)
3598
3599 (while (and (not has-schema) names)
3600 (setq has-schema (and
3601 (>= (length (car names)) schema-len)
3602 (string= schema-dot
3603 (downcase (substring (car names)
3604 0 schema-len))))
3605 names (cdr names)))
3606 (unless has-schema
3607 (sql-build-completions schema)))))
3608
3609 ;; Try to find the completion
3610 (cond
3611 ((not predicate)
3612 (try-completion string sql-completion-object))
3613 ((eq predicate t)
3614 (all-completions string sql-completion-object))
3615 ((eq predicate 'lambda)
3616 (test-completion string sql-completion-object))
3617 ((eq (car predicate) 'boundaries)
3618 (completion-boundaries string sql-completion-object nil (cdr predicate)))))))
3201 3619
3202(defun sql-read-table-name (prompt) 3620(defun sql-read-table-name (prompt)
3203 "Read the name of a database table." 3621 "Read the name of a database table."
3204 ;; TODO: Fetch table/view names from database and provide completion. 3622 (let* ((tname
3205 ;; Also implement thing-at-point if the buffer has valid names in it 3623 (and (buffer-local-value 'sql-contains-names (current-buffer))
3206 ;; (i.e. sql-mode, sql-interactive-mode, or sql-list-all buffers) 3624 (thing-at-point-looking-at
3207 (read-from-minibuffer prompt)) 3625 (concat "\\_<\\sw\\(:?\\sw\\|\\s_\\)*"
3626 "\\(?:[.]+\\sw\\(?:\\sw\\|\\s_\\)*\\)*\\_>"))
3627 (buffer-substring-no-properties (match-beginning 0)
3628 (match-end 0))))
3629 (sql-completion-sqlbuf (sql-find-sqli-buffer))
3630 (product (with-current-buffer sql-completion-sqlbuf sql-product))
3631 (completion-ignore-case t))
3632
3633 (if (sql-get-product-feature product :completion-object)
3634 (completing-read prompt (function sql-try-completion)
3635 nil nil tname)
3636 (read-from-minibuffer prompt tname))))
3208 3637
3209(defun sql-list-all (&optional enhanced) 3638(defun sql-list-all (&optional enhanced)
3210 "List all database objects." 3639 "List all database objects."
@@ -3212,7 +3641,11 @@ buffer is popped into a view window. "
3212 (let ((sqlbuf (sql-find-sqli-buffer))) 3641 (let ((sqlbuf (sql-find-sqli-buffer)))
3213 (unless sqlbuf 3642 (unless sqlbuf
3214 (error "No SQL interactive buffer found")) 3643 (error "No SQL interactive buffer found"))
3215 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil))) 3644 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil)
3645 (with-current-buffer sqlbuf
3646 ;; Contains the name of database objects
3647 (set (make-local-variable 'sql-contains-names) t)
3648 (set (make-local-variable 'sql-buffer) sqlbuf))))
3216 3649
3217(defun sql-list-table (name &optional enhanced) 3650(defun sql-list-table (name &optional enhanced)
3218 "List the details of a database table. " 3651 "List the details of a database table. "
@@ -3226,7 +3659,6 @@ buffer is popped into a view window. "
3226 (error "No table name specified")) 3659 (error "No table name specified"))
3227 (sql-execute-feature sqlbuf (format "*List %s*" name) 3660 (sql-execute-feature sqlbuf (format "*List %s*" name)
3228 :list-table enhanced name))) 3661 :list-table enhanced name)))
3229
3230 3662
3231 3663
3232;;; SQL mode -- uses SQL interactive mode 3664;;; SQL mode -- uses SQL interactive mode
@@ -3277,6 +3709,8 @@ you must tell Emacs. Here's how to do that in your `~/.emacs' file:
3277 (set (make-local-variable 'paragraph-start) "[\n\f]") 3709 (set (make-local-variable 'paragraph-start) "[\n\f]")
3278 ;; Abbrevs 3710 ;; Abbrevs
3279 (setq abbrev-all-caps 1) 3711 (setq abbrev-all-caps 1)
3712 ;; Contains the name of database objects
3713 (set (make-local-variable 'sql-contains-names) t)
3280 ;; Catch changes to sql-product and highlight accordingly 3714 ;; Catch changes to sql-product and highlight accordingly
3281 (add-hook 'hack-local-variables-hook 'sql-highlight-product t t)) 3715 (add-hook 'hack-local-variables-hook 'sql-highlight-product t t))
3282 3716
@@ -3362,7 +3796,7 @@ you entered, right above the output it created.
3362 sql-product)) 3796 sql-product))
3363 3797
3364 ;; Setup the mode. 3798 ;; Setup the mode.
3365 (setq major-mode 'sql-interactive-mode) ;FIXME: Use define-derived-mode. 3799 (setq major-mode 'sql-interactive-mode)
3366 (setq mode-name 3800 (setq mode-name
3367 (concat "SQLi[" (or (sql-get-product-feature sql-product :name) 3801 (concat "SQLi[" (or (sql-get-product-feature sql-product :name)
3368 (symbol-name sql-product)) "]")) 3802 (symbol-name sql-product)) "]"))
@@ -3385,9 +3819,18 @@ you entered, right above the output it created.
3385 (setq abbrev-all-caps 1) 3819 (setq abbrev-all-caps 1)
3386 ;; Exiting the process will call sql-stop. 3820 ;; Exiting the process will call sql-stop.
3387 (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop) 3821 (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop)
3388 ;; Save the connection name 3822 ;; Save the connection and login params
3389 (make-local-variable 'sql-connection) 3823 (set (make-local-variable 'sql-user) sql-user)
3390 ;; Create a usefull name for renaming this buffer later. 3824 (set (make-local-variable 'sql-database) sql-database)
3825 (set (make-local-variable 'sql-server) sql-server)
3826 (set (make-local-variable 'sql-port) sql-port)
3827 (set (make-local-variable 'sql-connection) sql-connection)
3828 ;; Contains the name of database objects
3829 (set (make-local-variable 'sql-contains-names) t)
3830 ;; Keep track of existing object names
3831 (set (make-local-variable 'sql-completion-object) nil)
3832 (set (make-local-variable 'sql-completion-column) nil)
3833 ;; Create a useful name for renaming this buffer later.
3391 (set (make-local-variable 'sql-alternate-buffer-name) 3834 (set (make-local-variable 'sql-alternate-buffer-name)
3392 (sql-make-alternate-buffer-name)) 3835 (sql-make-alternate-buffer-name))
3393 ;; User stuff. Initialize before the hook. 3836 ;; User stuff. Initialize before the hook.
@@ -3398,6 +3841,7 @@ you entered, right above the output it created.
3398 (set (make-local-variable 'sql-prompt-cont-regexp) 3841 (set (make-local-variable 'sql-prompt-cont-regexp)
3399 (sql-get-product-feature sql-product :prompt-cont-regexp)) 3842 (sql-get-product-feature sql-product :prompt-cont-regexp))
3400 (make-local-variable 'sql-output-newline-count) 3843 (make-local-variable 'sql-output-newline-count)
3844 (make-local-variable 'sql-preoutput-hold)
3401 (make-local-variable 'sql-output-by-send) 3845 (make-local-variable 'sql-output-by-send)
3402 (add-hook 'comint-preoutput-filter-functions 3846 (add-hook 'comint-preoutput-filter-functions
3403 'sql-interactive-remove-continuation-prompt nil t) 3847 'sql-interactive-remove-continuation-prompt nil t)
@@ -3450,7 +3894,7 @@ Sentinels will always get the two parameters PROCESS and EVENT."
3450 nil t initial 'sql-connection-history default))) 3894 nil t initial 'sql-connection-history default)))
3451 3895
3452;;;###autoload 3896;;;###autoload
3453(defun sql-connect (connection) 3897(defun sql-connect (connection &optional new-name)
3454 "Connect to an interactive session using CONNECTION settings. 3898 "Connect to an interactive session using CONNECTION settings.
3455 3899
3456See `sql-connection-alist' to see how to define connections and 3900See `sql-connection-alist' to see how to define connections and
@@ -3462,7 +3906,8 @@ is specified in the connection settings."
3462 ;; Prompt for the connection from those defined in the alist 3906 ;; Prompt for the connection from those defined in the alist
3463 (interactive 3907 (interactive
3464 (if sql-connection-alist 3908 (if sql-connection-alist
3465 (list (sql-read-connection "Connection: " nil '(nil))) 3909 (list (sql-read-connection "Connection: " nil '(nil))
3910 current-prefix-arg)
3466 nil)) 3911 nil))
3467 3912
3468 ;; Are there connections defined 3913 ;; Are there connections defined
@@ -3500,14 +3945,15 @@ is specified in the connection settings."
3500 (unless (member token set-params) 3945 (unless (member token set-params)
3501 (if plist 3946 (if plist
3502 (cons token plist) 3947 (cons token plist)
3503 token))))) 3948 token))))))
3504 ;; Remember the connection
3505 (sql-connection connection))
3506 3949
3507 ;; Set the remaining parameters and start the 3950 ;; Set the remaining parameters and start the
3508 ;; interactive session 3951 ;; interactive session
3509 (eval `(let ((,param-var ',rem-params)) 3952 (eval `(let ((sql-connection ,connection)
3510 (sql-product-interactive sql-product))))) 3953 (,param-var ',rem-params))
3954 (sql-product-interactive sql-product
3955 new-name)))))
3956
3511 (message "SQL Connection <%s> does not exist" connection) 3957 (message "SQL Connection <%s> does not exist" connection)
3512 nil))) 3958 nil)))
3513 (message "No SQL Connections defined") 3959 (message "No SQL Connections defined")
@@ -3521,39 +3967,51 @@ optionally is saved to the user's init file."
3521 3967
3522 (interactive "sNew connection name: ") 3968 (interactive "sNew connection name: ")
3523 3969
3524 (if sql-connection 3970 (unless (derived-mode-p 'sql-interactive-mode)
3525 (message "This session was started by a connection; it's already been saved.") 3971 (error "Not in a SQL interactive mode!"))
3526 3972
3527 (let ((login (sql-get-product-feature sql-product :sqli-login)) 3973 ;; Capture the buffer local settings
3528 (alist sql-connection-alist) 3974 (let* ((buf (current-buffer))
3529 connect) 3975 (connection (buffer-local-value 'sql-connection buf))
3530 3976 (product (buffer-local-value 'sql-product buf))
3531 ;; Remove the existing connection if the user says so 3977 (user (buffer-local-value 'sql-user buf))
3532 (when (and (assoc name alist) 3978 (database (buffer-local-value 'sql-database buf))
3533 (yes-or-no-p (format "Replace connection definition <%s>? " name))) 3979 (server (buffer-local-value 'sql-server buf))
3534 (setq alist (assq-delete-all name alist))) 3980 (port (buffer-local-value 'sql-port buf)))
3535 3981
3536 ;; Add the new connection if it doesn't exist 3982 (if connection
3537 (if (assoc name alist) 3983 (message "This session was started by a connection; it's already been saved.")
3538 (message "Connection <%s> already exists" name) 3984
3539 (setq connect 3985 (let ((login (sql-get-product-feature product :sqli-login))
3540 (append (list name) 3986 (alist sql-connection-alist)
3541 (sql-for-each-login 3987 connect)
3542 `(product ,@login) 3988
3543 (lambda (token _plist) 3989 ;; Remove the existing connection if the user says so
3544 (cond 3990 (when (and (assoc name alist)
3545 ((eq token 'product) `(sql-product ',sql-product)) 3991 (yes-or-no-p (format "Replace connection definition <%s>? " name)))
3546 ((eq token 'user) `(sql-user ,sql-user)) 3992 (setq alist (assq-delete-all name alist)))
3547 ((eq token 'database) `(sql-database ,sql-database)) 3993
3548 ((eq token 'server) `(sql-server ,sql-server)) 3994 ;; Add the new connection if it doesn't exist
3549 ((eq token 'port) `(sql-port ,sql-port))))))) 3995 (if (assoc name alist)
3550 3996 (message "Connection <%s> already exists" name)
3551 (setq alist (append alist (list connect))) 3997 (setq connect
3552 3998 (append (list name)
3553 ;; confirm whether we want to save the connections 3999 (sql-for-each-login
3554 (if (yes-or-no-p "Save the connections for future sessions? ") 4000 `(product ,@login)
3555 (customize-save-variable 'sql-connection-alist alist) 4001 (lambda (token _plist)
3556 (customize-set-variable 'sql-connection-alist alist)))))) 4002 (cond
4003 ((eq token 'product) `(sql-product ',product))
4004 ((eq token 'user) `(sql-user ,user))
4005 ((eq token 'database) `(sql-database ,database))
4006 ((eq token 'server) `(sql-server ,server))
4007 ((eq token 'port) `(sql-port ,port)))))))
4008
4009 (setq alist (append alist (list connect)))
4010
4011 ;; confirm whether we want to save the connections
4012 (if (yes-or-no-p "Save the connections for future sessions? ")
4013 (customize-save-variable 'sql-connection-alist alist)
4014 (customize-set-variable 'sql-connection-alist alist)))))))
3557 4015
3558(defun sql-connection-menu-filter (tail) 4016(defun sql-connection-menu-filter (tail)
3559 "Generates menu entries for using each connection." 4017 "Generates menu entries for using each connection."
@@ -3561,7 +4019,10 @@ optionally is saved to the user's init file."
3561 (mapcar 4019 (mapcar
3562 (lambda (conn) 4020 (lambda (conn)
3563 (vector 4021 (vector
3564 (format "Connection <%s>" (car conn)) 4022 (format "Connection <%s>\t%s" (car conn)
4023 (let ((sql-user "") (sql-database "")
4024 (sql-server "") (sql-port 0))
4025 (eval `(let ,(cdr conn) (sql-make-alternate-buffer-name)))))
3565 (list 'sql-connect (car conn)) 4026 (list 'sql-connect (car conn))
3566 t)) 4027 t))
3567 sql-connection-alist) 4028 sql-connection-alist)
@@ -3599,10 +4060,10 @@ the call to \\[sql-product-interactive] with
3599 ;; Get the value of product that we need 4060 ;; Get the value of product that we need
3600 (setq product 4061 (setq product
3601 (cond 4062 (cond
3602 ((and product ; Product specified
3603 (symbolp product)) product)
3604 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product 4063 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product
3605 (sql-read-product "SQL product: " sql-product)) 4064 (sql-read-product "SQL product: " sql-product))
4065 ((and product ; Product specified
4066 (symbolp product)) product)
3606 (t sql-product))) ; Default to sql-product 4067 (t sql-product))) ; Default to sql-product
3607 4068
3608 ;; If we have a product and it has a interactive mode 4069 ;; If we have a product and it has a interactive mode
@@ -3610,7 +4071,7 @@ the call to \\[sql-product-interactive] with
3610 (when (sql-get-product-feature product :sqli-comint-func) 4071 (when (sql-get-product-feature product :sqli-comint-func)
3611 ;; If no new name specified, try to pop to an active SQL 4072 ;; If no new name specified, try to pop to an active SQL
3612 ;; interactive for the same product 4073 ;; interactive for the same product
3613 (let ((buf (sql-find-sqli-buffer product))) 4074 (let ((buf (sql-find-sqli-buffer product sql-connection)))
3614 (if (and (not new-name) buf) 4075 (if (and (not new-name) buf)
3615 (pop-to-buffer buf) 4076 (pop-to-buffer buf)
3616 4077
@@ -3629,23 +4090,24 @@ the call to \\[sql-product-interactive] with
3629 (sql-get-product-feature product :sqli-options)) 4090 (sql-get-product-feature product :sqli-options))
3630 4091
3631 ;; Set SQLi mode. 4092 ;; Set SQLi mode.
3632 (setq new-sqli-buffer (current-buffer))
3633 (let ((sql-interactive-product product)) 4093 (let ((sql-interactive-product product))
3634 (sql-interactive-mode)) 4094 (sql-interactive-mode))
3635 4095
3636 ;; Set the new buffer name 4096 ;; Set the new buffer name
4097 (setq new-sqli-buffer (current-buffer))
3637 (when new-name 4098 (when new-name
3638 (sql-rename-buffer new-name)) 4099 (sql-rename-buffer new-name))
3639
3640 ;; Set `sql-buffer' in the new buffer and the start buffer
3641 (setq sql-buffer (buffer-name new-sqli-buffer)) 4100 (setq sql-buffer (buffer-name new-sqli-buffer))
4101
4102 ;; Set `sql-buffer' in the start buffer
3642 (with-current-buffer start-buffer 4103 (with-current-buffer start-buffer
3643 (setq sql-buffer (buffer-name new-sqli-buffer)) 4104 (when (derived-mode-p 'sql-mode)
3644 (run-hooks 'sql-set-sqli-hook)) 4105 (setq sql-buffer (buffer-name new-sqli-buffer))
4106 (run-hooks 'sql-set-sqli-hook)))
3645 4107
3646 ;; All done. 4108 ;; All done.
3647 (message "Login...done") 4109 (message "Login...done")
3648 (pop-to-buffer sql-buffer))))) 4110 (pop-to-buffer new-sqli-buffer)))))
3649 (message "No default SQL product defined. Set `sql-product'."))) 4111 (message "No default SQL product defined. Set `sql-product'.")))
3650 4112
3651(defun sql-comint (product params) 4113(defun sql-comint (product params)
@@ -3720,6 +4182,157 @@ The default comes from `process-coding-system-alist' and
3720 (setq parameter options)) 4182 (setq parameter options))
3721 (sql-comint product parameter))) 4183 (sql-comint product parameter)))
3722 4184
4185(defun sql-oracle-save-settings (sqlbuf)
4186 "Saves most SQL*Plus settings so they may be reset by \\[sql-redirect]."
4187 ;; Note: does not capture the following settings:
4188 ;;
4189 ;; APPINFO
4190 ;; BTITLE
4191 ;; COMPATIBILITY
4192 ;; COPYTYPECHECK
4193 ;; MARKUP
4194 ;; RELEASE
4195 ;; REPFOOTER
4196 ;; REPHEADER
4197 ;; SQLPLUSCOMPATIBILITY
4198 ;; TTITLE
4199 ;; USER
4200 ;;
4201
4202 (append
4203 ;; (apply 'concat (append
4204 ;; '("SET")
4205
4206 ;; option value...
4207 (sql-redirect-value
4208 sqlbuf
4209 (concat "SHOW ARRAYSIZE AUTOCOMMIT AUTOPRINT AUTORECOVERY AUTOTRACE"
4210 " CMDSEP COLSEP COPYCOMMIT DESCRIBE ECHO EDITFILE EMBEDDED"
4211 " ESCAPE FLAGGER FLUSH HEADING INSTANCE LINESIZE LNO LOBOFFSET"
4212 " LOGSOURCE LONG LONGCHUNKSIZE NEWPAGE NULL NUMFORMAT NUMWIDTH"
4213 " PAGESIZE PAUSE PNO RECSEP SERVEROUTPUT SHIFTINOUT SHOWMODE"
4214 " SPOOL SQLBLANKLINES SQLCASE SQLCODE SQLCONTINUE SQLNUMBER"
4215 " SQLPROMPT SUFFIX TAB TERMOUT TIMING TRIMOUT TRIMSPOOL VERIFY")
4216 "^.+$"
4217 "SET \\&")
4218
4219 ;; option "c" (hex xx)
4220 (sql-redirect-value
4221 sqlbuf
4222 (concat "SHOW BLOCKTERMINATOR CONCAT DEFINE SQLPREFIX SQLTERMINATOR"
4223 " UNDERLINE HEADSEP RECSEPCHAR")
4224 "^\\(.+\\) (hex ..)$"
4225 "SET \\1")
4226
4227 ;; FEDDBACK ON for 99 or more rows
4228 ;; feedback OFF
4229 (sql-redirect-value
4230 sqlbuf
4231 "SHOW FEEDBACK"
4232 "^\\(?:FEEDBACK ON for \\([[:digit:]]+\\) or more rows\\|feedback \\(OFF\\)\\)"
4233 "SET FEEDBACK \\1\\2")
4234
4235 ;; wrap : lines will be wrapped
4236 ;; wrap : lines will be truncated
4237 (list (concat "SET WRAP "
4238 (if (string=
4239 (car (sql-redirect-value
4240 sqlbuf
4241 "SHOW WRAP"
4242 "^wrap : lines will be \\(wrapped\\|truncated\\)" 1))
4243 "wrapped")
4244 "ON" "OFF")))))
4245
4246(defun sql-oracle-restore-settings (sqlbuf saved-settings)
4247 "Restore the SQL*Plus settings in SAVED-SETTINGS."
4248
4249 ;; Remove any settings that haven't changed
4250 (mapc
4251 (lambda (one-cur-setting)
4252 (setq saved-settings (delete one-cur-setting saved-settings)))
4253 (sql-oracle-save-settings sqlbuf))
4254
4255 ;; Restore the changed settings
4256 (sql-redirect sqlbuf saved-settings))
4257
4258(defun sql-oracle-list-all (sqlbuf outbuf enhanced table-name)
4259 ;; Query from USER_OBJECTS or ALL_OBJECTS
4260 (let ((settings (sql-oracle-save-settings sqlbuf))
4261 (simple-sql
4262 (concat
4263 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4264 ", x.object_name AS SQL_EL_NAME "
4265 "FROM user_objects x "
4266 "WHERE x.object_type NOT LIKE '%% BODY' "
4267 "ORDER BY 2, 1;"))
4268 (enhanced-sql
4269 (concat
4270 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4271 ", x.owner ||'.'|| x.object_name AS SQL_EL_NAME "
4272 "FROM all_objects x "
4273 "WHERE x.object_type NOT LIKE '%% BODY' "
4274 "AND x.owner <> 'SYS' "
4275 "ORDER BY 2, 1;")))
4276
4277 (sql-redirect sqlbuf
4278 (concat "SET LINESIZE 80 PAGESIZE 50000 TRIMOUT ON"
4279 " TAB OFF TIMING OFF FEEDBACK OFF"))
4280
4281 (sql-redirect sqlbuf
4282 (list "COLUMN SQL_EL_TYPE HEADING \"Type\" FORMAT A19"
4283 "COLUMN SQL_EL_NAME HEADING \"Name\""
4284 (format "COLUMN SQL_EL_NAME FORMAT A%d"
4285 (if enhanced 60 35))))
4286
4287 (sql-redirect sqlbuf
4288 (if enhanced enhanced-sql simple-sql)
4289 outbuf)
4290
4291 (sql-redirect sqlbuf
4292 '("COLUMN SQL_EL_NAME CLEAR"
4293 "COLUMN SQL_EL_TYPE CLEAR"))
4294
4295 (sql-oracle-restore-settings sqlbuf settings)))
4296
4297(defun sql-oracle-list-table (sqlbuf outbuf enhanced table-name)
4298 "Implements :list-table under Oracle."
4299 (let ((settings (sql-oracle-save-settings sqlbuf)))
4300
4301 (sql-redirect sqlbuf
4302 (format
4303 (concat "SET LINESIZE %d PAGESIZE 50000"
4304 " DESCRIBE DEPTH 1 LINENUM OFF INDENT ON")
4305 (max 65 (min 120 (window-width)))))
4306
4307 (sql-redirect sqlbuf (format "DESCRIBE %s" table-name)
4308 outbuf)
4309
4310 (sql-oracle-restore-settings sqlbuf settings)))
4311
4312(defcustom sql-oracle-completion-types '("FUNCTION" "PACKAGE" "PROCEDURE"
4313 "SEQUENCE" "SYNONYM" "TABLE" "TRIGGER"
4314 "TYPE" "VIEW")
4315 "List of object types to include for completion under Oracle.
4316
4317See the distinct values in ALL_OBJECTS.OBJECT_TYPE for possible values."
4318 :version "24.1"
4319 :type '(repeat string)
4320 :group 'SQL)
4321
4322(defun sql-oracle-completion-object (sqlbuf schema)
4323 (sql-redirect-value
4324 sqlbuf
4325 (concat
4326 "SELECT CHR(1)||"
4327 (if schema
4328 (format "owner||'.'||object_name AS o FROM all_objects WHERE owner = %s AND "
4329 (sql-str-literal (upcase schema)))
4330 "object_name AS o FROM user_objects WHERE ")
4331 "temporary = 'N' AND generated = 'N' AND secondary = 'N' AND "
4332 "object_type IN ("
4333 (mapconcat (function sql-str-literal) sql-oracle-completion-types ",")
4334 ");")
4335 "^[\001]\\(.+\\)$" 1))
3723 4336
3724 4337
3725;;;###autoload 4338;;;###autoload
@@ -3858,6 +4471,9 @@ The default comes from `process-coding-system-alist' and
3858 (setq params (append options params)) 4471 (setq params (append options params))
3859 (sql-comint product params))) 4472 (sql-comint product params)))
3860 4473
4474(defun sql-sqlite-completion-object (sqlbuf schema)
4475 (sql-redirect-value sqlbuf ".tables" "\\sw\\(?:\\sw\\|\\s_\\)*" 0))
4476
3861 4477
3862 4478
3863;;;###autoload 4479;;;###autoload
@@ -4112,6 +4728,33 @@ Try to set `comint-output-filter-functions' like this:
4112 (setq params (append (list "-p" sql-port) params))) 4728 (setq params (append (list "-p" sql-port) params)))
4113 (sql-comint product params))) 4729 (sql-comint product params)))
4114 4730
4731(defun sql-postgres-completion-object (sqlbuf schema)
4732 (let (cl re fs a r)
4733 (sql-redirect sqlbuf "\\t on")
4734 (setq a (car (sql-redirect-value sqlbuf "\\a" "Output format is \\(.*\\)[.]$" 1)))
4735 (when (string= a "aligned")
4736 (sql-redirect sqlbuf "\\a"))
4737 (setq fs (or (car (sql-redirect-value sqlbuf "\\f" "Field separator is \"\\(.\\)[.]$" 1)) "|"))
4738
4739 (setq re (concat "^\\([^" fs "]*\\)" fs "\\([^" fs "]*\\)" fs "[^" fs "]*" fs "[^" fs "]*$"))
4740 (setq cl (if (not schema)
4741 (sql-redirect-value sqlbuf "\\d" re '(1 2))
4742 (append (sql-redirect-value sqlbuf (format "\\dt %s.*" schema) re '(1 2))
4743 (sql-redirect-value sqlbuf (format "\\dv %s.*" schema) re '(1 2))
4744 (sql-redirect-value sqlbuf (format "\\ds %s.*" schema) re '(1 2)))))
4745
4746 ;; Restore tuples and alignment to what they were
4747 (sql-redirect sqlbuf "\\t off")
4748 (when (not (string= a "aligned"))
4749 (sql-redirect sqlbuf "\\a"))
4750
4751 ;; Return the list of table names (public schema name can be omitted)
4752 (mapcar (lambda (tbl)
4753 (if (string= (car tbl) "public")
4754 (cadr tbl)
4755 (format "%s.%s" (car tbl) (cadr tbl))))
4756 cl)))
4757
4115 4758
4116 4759
4117;;;###autoload 4760;;;###autoload
@@ -4199,8 +4842,7 @@ The default comes from `process-coding-system-alist' and
4199 "Create comint buffer and connect to DB2." 4842 "Create comint buffer and connect to DB2."
4200 ;; Put all parameters to the program (if defined) in a list and call 4843 ;; Put all parameters to the program (if defined) in a list and call
4201 ;; make-comint. 4844 ;; make-comint.
4202 (sql-comint product options) 4845 (sql-comint product options))
4203)
4204 4846
4205;;;###autoload 4847;;;###autoload
4206(defun sql-linter (&optional buffer) 4848(defun sql-linter (&optional buffer)
@@ -4257,3 +4899,6 @@ buffer.
4257(provide 'sql) 4899(provide 'sql)
4258 4900
4259;;; sql.el ends here 4901;;; sql.el ends here
4902
4903; LocalWords: sql SQL SQLite sqlite Sybase Informix MySQL
4904; LocalWords: Postgres SQLServer SQLi