1;;; sql.el --- specialized comint.el for SQL interpreters
2
3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4;; Free Software Foundation, Inc.
5
6;; Author: Alex Schroeder <alex@gnu.org>
7;; Maintainer: Michael Mauger <mmaug@yahoo.com>
8;; Version: 2.0.2
9;; Keywords: comm languages processes
10;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el
11;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING.  If not, write to the
27;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28;; Boston, MA 02110-1301, USA.
29
30;;; Commentary:
31
32;; Please send bug reports and bug fixes to the mailing list at
33;; help-gnu-emacs@gnu.org.  If you want to subscribe to the mailing
34;; list, see the web page at
35;; http://lists.gnu.org/mailman/listinfo/help-gnu-emacs for
36;; instructions.  I monitor this list actively.  If you send an e-mail
37;; to Alex Schroeder it usually makes it to me when Alex has a chance
38;; to forward them along (Thanks, Alex).
39
40;; This file provides a sql-mode and a sql-interactive-mode.  The
41;; original goals were two simple modes providing syntactic
42;; highlighting.  The interactive mode had to provide a command-line
43;; history; the other mode had to provide "send region/buffer to SQL
44;; interpreter" functions.  "simple" in this context means easy to
45;; use, easy to maintain and little or no bells and whistles.  This
46;; has changed somewhat as experience with the mode has accumulated.
47
48;; Support for different flavors of SQL and command interpreters was
49;; available in early versions of sql.el.  This support has been
50;; extended and formalized in later versions.  Part of the impetus for
51;; the improved support of SQL flavors was borne out of the current
52;; maintainer's consulting experience.  In the past fifteen years, I
53;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer.
54;; On some assignments, I have used two or more of these concurrently.
55
56;; If anybody feels like extending this sql mode, take a look at the
57;; above mentioned modes and write a sqlx-mode on top of this one.  If
58;; this proves to be difficult, please suggest changes that will
59;; facilitate your plans.  Facilities have been provided to add
60;; products and product-specific configuration.
61
62;; sql-interactive-mode is used to interact with a SQL interpreter
63;; process in a SQLi buffer (usually called `*SQL*').  The SQLi buffer
64;; is created by calling a SQL interpreter-specific entry function or
65;; sql-product-interactive.  Do *not* call sql-interactive-mode by
66;; itself.
67
68;; The list of currently supported interpreters and the corresponding
69;; entry function used to create the SQLi buffers is shown with
70;; `sql-help' (M-x sql-help).
71
72;; Since sql-interactive-mode is built on top of the general
73;; command-interpreter-in-a-buffer mode (comint mode), it shares a
74;; common base functionality, and a common set of bindings, with all
75;; modes derived from comint mode.  This makes these modes easier to
76;; use.
77
78;; sql-mode can be used to keep editing SQL statements.  The SQL
79;; statements can be sent to the SQL process in the SQLi buffer.
80
81;; For documentation on the functionality provided by comint mode, and
82;; the hooks available for customizing it, see the file `comint.el'.
83
84;; Hint for newbies: take a look at `dabbrev-expand', `abbrev-mode', and
85;; `imenu-add-menubar-index'.
86
87;;; Requirements for Emacs 19.34:
88
89;; If you are using Emacs 19.34, you will have to get and install
90;; the file regexp-opt.el
91;; <URL:ftp://ftp.ifi.uio.no/pub/emacs/emacs-20.3/lisp/emacs-lisp/regexp-opt.el>
92;; and the custom package
93;; <URL:http://www.dina.kvl.dk/~abraham/custom/>.
94
95;;; Bugs:
96
97;; sql-ms now uses osql instead of isql.  Osql flushes its error
98;; stream more frequently than isql so that error messages are
99;; available.  There is no prompt and some output still is buffered.
100;; This improves the interaction under Emacs but it still is somewhat
101;; awkward.
102
103;; Quoted identifiers are not supported for hilighting.  Most
104;; databases support the use of double quoted strings in place of
105;; identifiers; ms (Microsoft SQLServer) also supports identifiers
106;; enclosed within brackets [].
107
108;; ChangeLog available on request.
109
110;;; Product Support:
111
112;; To add support for additional SQL products the following steps
113;; must be followed ("xyz" is the name of the product in the examples
114;; below):
115
116;; 1) Add the product to `sql-product' choice list.
117
118;;     (const :tag "XyzDB" xyz)
119
120;; 2) Add an entry to the `sql-product-alist' list.
121
122;;     (xyz
123;;      :font-lock sql-mode-xyz-font-lock-keywords
124;;      :sqli-login (user password server database)
125;;      :sqli-connect sql-connect-xyz
126;;      :sqli-prompt-regexp "^xyzdb> "
127;;      :sqli-prompt-length 7
128;;      :sqli-input-sender nil
129;;      :syntax-alist ((?# . "w")))
130
131;; 3) Add customizable values for the product interpreter and options.
132
133;;     ;; Customization for XyzDB
134;;
135;;     (defcustom sql-xyz-program "ixyz"
136;;       "*Command to start ixyz by XyzDB."
137;;       :type 'file
138;;       :group 'SQL)
139;;
140;;     (defcustom sql-xyz-options '("-X" "-Y" "-Z")
141;;       "*List of additional options for `sql-xyz-program'."
142;;       :type '(repeat string)
143;;       :group 'SQL)
144
145;; 4) Add an entry to SQL->Product submenu.
146
147;;     ["XyzDB" sql-highlight-xyz-keywords
148;;      :style radio
149;;      :selected (eq sql-product 'xyz)]
150
151;; 5) Add the font-lock specifications.  At a minimum, default to
152;;    using ANSI keywords.  See sql-mode-oracle-font-lock-keywords for
153;;    a more complex example.
154
155;;     (defvar sql-mode-xyz-font-lock-keywords nil
156;;       "XyzDB SQL keywords used by font-lock.")
157
158;; 6) Add a product highlighting function.
159
160;;     (defun sql-highlight-xyz-keywords ()
161;;       "Highlight XyzDB keywords."
162;;       (interactive)
163;;       (sql-set-product 'xyz))
164
165;; 7) Add an autoloaded SQLi function.
166
167;;     ;;;###autoload
168;;     (defun sql-xyz ()
169;;       "Run ixyz by XyzDB as an inferior process."
170;;       (interactive)
171;;       (sql-product-interactive 'xyz))
172
173;; 8) Add a connect function which formats the command line arguments
174;;    and starts the product interpreter in a comint buffer.  See the
175;;    existing connect functions for examples of the types of
176;;    processing available.
177
178;;     (defun sql-connect-xyz ()
179;;       "Create comint buffer and connect to XyzDB using the login
180;;     parameters and command options."
181;;
182;;         ;; Do something with `sql-user', `sql-password',
183;;         ;; `sql-database', and `sql-server'.
184;;         (let ((params sql-xyz-options))
185;;           (if (not (string= "" sql-server))
186;;              (setq params (append (list "-S" sql-server) params)))
187;;           (if (not (string= "" sql-database))
188;;               (setq params (append (list "-D" sql-database) params)))
189;;           (if (not (string= "" sql-password))
190;;               (setq params (append (list "-P" sql-password) params)))
191;;           (if (not (string= "" sql-user))
192;;               (setq params (append (list "-U" sql-user) params)))
193;;           (set-buffer (apply 'make-comint "SQL" sql-xyz-program
194;;                              nil params))))
195
196;; 9) Save and compile sql.el.
197
198;;; To Do:
199
200;; Add better hilight support for other brands; there is a bias towards
201;; Oracle because that's what I use at work.  Anybody else just send in
202;; your lists of reserved words, keywords and builtin functions!  As
203;; long as I don't receive any feedback, everything is hilighted with
204;; ANSI keywords only.  I received the list of ANSI keywords from a
205;; user; if you know of any changes, let me know.
206
207;; Add different hilighting levels.
208
209;;; Thanks to all the people who helped me out:
210
211;; Alex Schroeder <alex@gnu.org>
212;; Kai Blauberg <kai.blauberg@metla.fi>
213;; <ibalaban@dalet.com>
214;; Yair Friedman <yfriedma@JohnBryce.Co.Il>
215;; Gregor Zych <zych@pool.informatik.rwth-aachen.de>
216;; nino <nino@inform.dk>
217;; Berend de Boer <berend@pobox.com>
218;; Adam Jenkins <adam@thejenkins.org>
219;; Michael Mauger <mmaug@yahoo.com> -- improved product support
220;; Drew Adams <drew.adams@oracle.com> -- Emacs 20 support
221;; Harald Maier <maierh@myself.com> -- sql-send-string
222;; Stefan Monnier <monnier@iro.umontreal.ca> -- font-lock corrections
223
224
225
226;;; Code:
227
228(require 'comint)
229;; Need the following to allow GNU Emacs 19 to compile the file.
230(eval-when-compile
231  (require 'regexp-opt))
232(require 'custom)
233(eval-when-compile ;; needed in Emacs 19, 20
234  (setq max-specpdl-size 2000))
235
236(defvar font-lock-keyword-face)
237(defvar font-lock-set-defaults)
238(defvar font-lock-string-face)
239
240;;; Allow customization
241
242(defgroup SQL nil
243  "Running a SQL interpreter from within Emacs buffers."
244  :version "20.4"
245  :group 'processes)
246
247;; These four variables will be used as defaults, if set.
248
249(defcustom sql-user ""
250  "*Default username."
251  :type 'string
252  :group 'SQL)
253
254(defcustom sql-password ""
255  "*Default password.
256
257Storing your password in a textfile such as ~/.emacs could be dangerous.
258Customizing your password will store it in your ~/.emacs file."
259  :type 'string
260  :group 'SQL)
261
262(defcustom sql-database ""
263  "*Default database."
264  :type 'string
265  :group 'SQL)
266
267(defcustom sql-server ""
268  "*Default server or host."
269  :type 'string
270  :group 'SQL)
271
272;; SQL Product support
273(defcustom sql-product 'ansi
274  "*Select the SQL database product used so that buffers can be
275highlighted properly when you open them."
276  :type '(choice (const :tag "ANSI" ansi)
277		 (const :tag "DB2" db2)
278		 (const :tag "Informix" informix)
279		 (const :tag "Ingres" ingres)
280		 (const :tag "Interbase" interbase)
281		 (const :tag "Linter" linter)
282		 (const :tag "Microsoft" ms)
283		 (const :tag "MySQL" mysql)
284		 (const :tag "Oracle" oracle)
285		 (const :tag "PostGres" postgres)
286		 (const :tag "Solid" solid)
287		 (const :tag "SQLite" sqlite)
288		 (const :tag "Sybase" sybase))
289  :group 'SQL)
290
291(defvar sql-interactive-product nil
292  "Product under `sql-interactive-mode'.")
293
294(defvar sql-product-alist
295  '((ansi
296     :font-lock sql-mode-ansi-font-lock-keywords)
297    (db2
298     :font-lock sql-mode-db2-font-lock-keywords
299     :sqli-login nil
300     :sqli-connect sql-connect-db2
301     :sqli-prompt-regexp "^db2 => "
302     :sqli-prompt-length 7)
303    (informix
304     :font-lock sql-mode-informix-font-lock-keywords
305     :sqli-login (database)
306     :sqli-connect sql-connect-informix
307     :sqli-prompt-regexp "^SQL> "
308     :sqli-prompt-length 5)
309    (ingres
310     :font-lock sql-mode-ingres-font-lock-keywords
311     :sqli-login (database)
312     :sqli-connect sql-connect-ingres
313     :sqli-prompt-regexp "^\* "
314     :sqli-prompt-length 2)
315    (interbase
316     :font-lock sql-mode-interbase-font-lock-keywords
317     :sqli-login (user password database)
318     :sqli-connect sql-connect-interbase
319     :sqli-prompt-regexp "^SQL> "
320     :sqli-prompt-length 5)
321    (linter
322     :font-lock sql-mode-linter-font-lock-keywords
323     :sqli-login (user password database server)
324     :sqli-connect sql-connect-linter
325     :sqli-prompt-regexp "^SQL>"
326     :sqli-prompt-length 4)
327    (ms
328     :font-lock sql-mode-ms-font-lock-keywords
329     :sqli-login (user password server database)
330     :sqli-connect sql-connect-ms
331     :sqli-prompt-regexp "^[0-9]*>"
332     :sqli-prompt-length 5
333     :syntax-alist ((?@ . "w")))
334    (mysql
335     :font-lock sql-mode-mysql-font-lock-keywords
336     :sqli-login (user password database server)
337     :sqli-connect sql-connect-mysql
338     :sqli-prompt-regexp "^mysql> "
339     :sqli-prompt-length 6)
340    (oracle
341     :font-lock sql-mode-oracle-font-lock-keywords
342     :sqli-login (user password database)
343     :sqli-connect sql-connect-oracle
344     :sqli-prompt-regexp "^SQL> "
345     :sqli-prompt-length 5
346     :syntax-alist ((?$ . "w") (?# . "w")))
347    (postgres
348     :font-lock sql-mode-postgres-font-lock-keywords
349     :sqli-login (user database server)
350     :sqli-connect sql-connect-postgres
351     :sqli-prompt-regexp "^.*[#>] *"
352     :sqli-prompt-length 5)
353    (solid
354     :font-lock sql-mode-solid-font-lock-keywords
355     :sqli-login (user password server)
356     :sqli-connect sql-connect-solid
357     :sqli-prompt-regexp "^"
358     :sqli-prompt-length 0)
359    (sqlite
360     :font-lock sql-mode-sqlite-font-lock-keywords
361     :sqli-login (user password server database)
362     :sqli-connect sql-connect-sqlite
363     :sqli-prompt-regexp "^sqlite> "
364     :sqli-prompt-length 8)
365    (sybase
366     :font-lock sql-mode-sybase-font-lock-keywords
367     :sqli-login (server user password database)
368     :sqli-connect sql-connect-sybase
369     :sqli-prompt-regexp "^SQL> "
370     :sqli-prompt-length 5
371     :syntax-alist ((?@ . "w")))
372    )
373  "This variable contains a list of product features for each of the
374SQL products handled by `sql-mode'.  Without an entry in this list a
375product will not be properly highlighted and will not support
376`sql-interactive-mode'.
377
378Each element in the list is in the following format:
379
380 \(PRODUCT FEATURE VALUE ...)
381
382where PRODUCT is the appropriate value of `sql-product'.  The product
383name is then followed by FEATURE-VALUE pairs.  If a FEATURE is not
384specified, its VALUE is treated as nil.  FEATURE must be one of the
385following:
386
387 :font-lock             name of the variable containing the product
388                        specific font lock highlighting patterns.
389
390 :sqli-login            a list of login parameters (i.e., user,
391                        password, database and server) needed to
392                        connect to the database.
393
394 :sqli-connect          the name of a function which accepts no
395                        parameters that will use the values of
396                        `sql-user', `sql-password',
397                        `sql-database' and `sql-server' to open a
398                        comint buffer and connect to the
399                        database.  Do product specific
400                        configuration of comint in this function.
401
402 :sqli-prompt-regexp    a regular expression string that matches
403                        the prompt issued by the product
404                        interpreter.  (Not needed in 21.3+)
405
406 :sqli-prompt-length    the length of the prompt on the line.(Not
407                        needed in 21.3+)
408
409 :syntax-alist          an alist of syntax table entries to enable
410                        special character treatment by font-lock and
411                        imenu. ")
412
413;; misc customization of sql.el behaviour
414
415(defcustom sql-electric-stuff nil
416  "Treat some input as electric.
417If set to the symbol `semicolon', then hitting `;' will send current
418input in the SQLi buffer to the process.
419If set to the symbol `go', then hitting `go' on a line by itself will
420send current input in the SQLi buffer to the process.
421If set to nil, then you must use \\[comint-send-input] in order to send
422current input in the SQLi buffer to the process."
423  :type '(choice (const :tag "Nothing" nil)
424		 (const :tag "The semikolon `;'" semicolon)
425		 (const :tag "The string `go' by itself" go))
426  :version "20.8"
427  :group 'SQL)
428
429(defcustom sql-pop-to-buffer-after-send-region nil
430  "*If t, pop to the buffer SQL statements are sent to.
431
432After a call to `sql-send-region' or `sql-send-buffer',
433the window is split and the SQLi buffer is shown.  If this
434variable is not nil, that buffer's window will be selected
435by calling `pop-to-buffer'.  If this variable is nil, that
436buffer is shown using `display-buffer'."
437  :type 'boolean
438  :group 'SQL)
439
440;; imenu support for sql-mode.
441
442(defvar sql-imenu-generic-expression
443  ;; Items are in reverse order because they are rendered in reverse.
444  '(("Rules/Defaults" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(rule\\|default\\)\\s-+\\(\\w+\\)" 3)
445    ("Sequences" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*sequence\\s-+\\(\\w+\\)" 2)
446    ("Triggers" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*trigger\\s-+\\(\\w+\\)" 2)
447    ("Functions" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?function\\s-+\\(\\w+\\)" 3)
448    ("Procedures" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4)
449    ("Packages" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3)
450    ("Indexes" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*index\\s-+\\(\\w+\\)" 2)
451    ("Tables/Views" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(table\\|view\\)\\s-+\\(\\w+\\)" 3))
452  "Define interesting points in the SQL buffer for `imenu'.
453
454This is used to set `imenu-generic-expression' when SQL mode is
455entered.  Subsequent changes to sql-imenu-generic-expression will not
456affect existing SQL buffers because imenu-generic-expression is a
457local variable.")
458
459;; history file
460
461(defcustom sql-input-ring-file-name nil
462  "*If non-nil, name of the file to read/write input history.
463
464You have to set this variable if you want the history of your commands
465saved from one Emacs session to the next.  If this variable is set,
466exiting the SQL interpreter in an SQLi buffer will write the input
467history to the specified file.  Starting a new process in a SQLi buffer
468will read the input history from the specified file.
469
470This is used to initialize `comint-input-ring-file-name'.
471
472Note that the size of the input history is determined by the variable
473`comint-input-ring-size'."
474  :type '(choice (const :tag "none" nil)
475		 (file))
476  :group 'SQL)
477
478(defcustom sql-input-ring-separator "\n--\n"
479  "*Separator between commands in the history file.
480
481If set to \"\\n\", each line in the history file will be interpreted as
482one command.  Multi-line commands are split into several commands when
483the input ring is initialized from a history file.
484
485This variable used to initialize `comint-input-ring-separator'.
486`comint-input-ring-separator' is part of Emacs 21; if your Emacs
487does not have it, setting `sql-input-ring-separator' will have no
488effect.  In that case multiline commands will be split into several
489commands when the input history is read, as if you had set
490`sql-input-ring-separator' to \"\\n\"."
491  :type 'string
492  :group 'SQL)
493
494;; The usual hooks
495
496(defcustom sql-interactive-mode-hook '()
497  "*Hook for customizing `sql-interactive-mode'."
498  :type 'hook
499  :group 'SQL)
500
501(defcustom sql-mode-hook '()
502  "*Hook for customizing `sql-mode'."
503  :type 'hook
504  :group 'SQL)
505
506(defcustom sql-set-sqli-hook '()
507  "*Hook for reacting to changes of `sql-buffer'.
508
509This is called by `sql-set-sqli-buffer' when the value of `sql-buffer'
510is changed."
511  :type 'hook
512  :group 'SQL)
513
514;; Customization for Oracle
515
516(defcustom sql-oracle-program "sqlplus"
517  "*Command to start sqlplus by Oracle.
518
519Starts `sql-interactive-mode' after doing some setup.
520
521Under NT, \"sqlplus\" usually starts the sqlplus \"GUI\".  In order to
522start the sqlplus console, use \"plus33\" or something similar.  You
523will find the file in your Orant\\bin directory.
524
525The program can also specify a TCP connection.  See `make-comint'."
526  :type 'file
527  :group 'SQL)
528
529(defcustom sql-oracle-options nil
530  "*List of additional options for `sql-oracle-program'."
531  :type '(repeat string)
532  :version "20.8"
533  :group 'SQL)
534
535;; Customization for SQLite
536
537(defcustom sql-sqlite-program "sqlite"
538  "*Command to start SQLite.
539
540Starts `sql-interactive-mode' after doing some setup.
541
542The program can also specify a TCP connection.  See `make-comint'."
543  :type 'file
544  :group 'SQL)
545
546(defcustom sql-sqlite-options nil
547  "*List of additional options for `sql-sqlite-program'.
548The following list of options is reported to make things work
549on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
550  :type '(repeat string)
551  :version "20.8"
552  :group 'SQL)
553
554;; Customization for MySql
555
556(defcustom sql-mysql-program "mysql"
557  "*Command to start mysql by TcX.
558
559Starts `sql-interactive-mode' after doing some setup.
560
561The program can also specify a TCP connection.  See `make-comint'."
562  :type 'file
563  :group 'SQL)
564
565(defcustom sql-mysql-options nil
566  "*List of additional options for `sql-mysql-program'.
567The following list of options is reported to make things work
568on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
569  :type '(repeat string)
570  :version "20.8"
571  :group 'SQL)
572
573;; Customization for Solid
574
575(defcustom sql-solid-program "solsql"
576  "*Command to start SOLID SQL Editor.
577
578Starts `sql-interactive-mode' after doing some setup.
579
580The program can also specify a TCP connection.  See `make-comint'."
581  :type 'file
582  :group 'SQL)
583
584;; Customization for SyBase
585
586(defcustom sql-sybase-program "isql"
587  "*Command to start isql by SyBase.
588
589Starts `sql-interactive-mode' after doing some setup.
590
591The program can also specify a TCP connection.  See `make-comint'."
592  :type 'file
593  :group 'SQL)
594
595(defcustom sql-sybase-options nil
596  "*List of additional options for `sql-sybase-program'.
597Some versions of isql might require the -n option in order to work."
598  :type '(repeat string)
599  :version "20.8"
600  :group 'SQL)
601
602;; Customization for Informix
603
604(defcustom sql-informix-program "dbaccess"
605  "*Command to start dbaccess by Informix.
606
607Starts `sql-interactive-mode' after doing some setup.
608
609The program can also specify a TCP connection.  See `make-comint'."
610  :type 'file
611  :group 'SQL)
612
613;; Customization for Ingres
614
615(defcustom sql-ingres-program "sql"
616  "*Command to start sql by Ingres.
617
618Starts `sql-interactive-mode' after doing some setup.
619
620The program can also specify a TCP connection.  See `make-comint'."
621  :type 'file
622  :group 'SQL)
623
624;; Customization for Microsoft
625
626(defcustom sql-ms-program "osql"
627  "*Command to start osql by Microsoft.
628
629Starts `sql-interactive-mode' after doing some setup.
630
631The program can also specify a TCP connection.  See `make-comint'."
632  :type 'file
633  :group 'SQL)
634
635(defcustom sql-ms-options '("-w" "300" "-n")
636  ;; -w is the linesize
637  "*List of additional options for `sql-ms-program'."
638  :type '(repeat string)
639  :version "22.1"
640  :group 'SQL)
641
642;; Customization for Postgres
643
644(defcustom sql-postgres-program "psql"
645  "Command to start psql by Postgres.
646
647Starts `sql-interactive-mode' after doing some setup.
648
649The program can also specify a TCP connection.  See `make-comint'."
650  :type 'file
651  :group 'SQL)
652
653(defcustom sql-postgres-options '("-P" "pager=off")
654  "*List of additional options for `sql-postgres-program'.
655The default setting includes the -P option which breaks older versions
656of the psql client (such as version 6.5.3).  The -P option is equivalent
657to the --pset option.  If you want the psql to prompt you for a user
658name, add the string \"-u\" to the list of options.  If you want to
659provide a user name on the command line (newer versions such as 7.1),
660add your name with a \"-U\" prefix (such as \"-Umark\") to the list."
661  :type '(repeat string)
662  :version "20.8"
663  :group 'SQL)
664
665;; Customization for Interbase
666
667(defcustom sql-interbase-program "isql"
668  "*Command to start isql by Interbase.
669
670Starts `sql-interactive-mode' after doing some setup.
671
672The program can also specify a TCP connection.  See `make-comint'."
673  :type 'file
674  :group 'SQL)
675
676(defcustom sql-interbase-options nil
677  "*List of additional options for `sql-interbase-program'."
678  :type '(repeat string)
679  :version "20.8"
680  :group 'SQL)
681
682;; Customization for DB2
683
684(defcustom sql-db2-program "db2"
685  "*Command to start db2 by IBM.
686
687Starts `sql-interactive-mode' after doing some setup.
688
689The program can also specify a TCP connection.  See `make-comint'."
690  :type 'file
691  :group 'SQL)
692
693(defcustom sql-db2-options nil
694  "*List of additional options for `sql-db2-program'."
695  :type '(repeat string)
696  :version "20.8"
697  :group 'SQL)
698
699;; Customization for Linter
700
701(defcustom sql-linter-program "inl"
702  "*Command to start inl by RELEX.
703
704Starts `sql-interactive-mode' after doing some setup."
705  :type 'file
706  :group 'SQL)
707
708(defcustom sql-linter-options nil
709  "*List of additional options for `sql-linter-program'."
710  :type '(repeat string)
711  :version "21.3"
712  :group 'SQL)
713
714
715
716;;; Variables which do not need customization
717
718(defvar sql-user-history nil
719  "History of usernames used.")
720
721(defvar sql-database-history nil
722  "History of databases used.")
723
724(defvar sql-server-history nil
725  "History of servers used.")
726
727;; Passwords are not kept in a history.
728
729(defvar sql-buffer nil
730  "Current SQLi buffer.
731
732The global value of sql-buffer is the name of the latest SQLi buffer
733created.  Any SQL buffer created will make a local copy of this value.
734See `sql-interactive-mode' for more on multiple sessions.  If you want
735to change the SQLi buffer a SQL mode sends its SQL strings to, change
736the local value of `sql-buffer' using \\[sql-set-sqli-buffer].")
737
738(defvar sql-prompt-regexp nil
739  "Prompt used to initialize `comint-prompt-regexp'.
740
741You can change `sql-prompt-regexp' on `sql-interactive-mode-hook'.")
742
743(defvar sql-prompt-length 0
744  "Prompt used to set `left-margin' in `sql-interactive-mode'.
745
746You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
747
748(defvar sql-alternate-buffer-name nil
749  "Buffer-local string used to possibly rename the SQLi buffer.
750
751Used by `sql-rename-buffer'.")
752
753;; Keymap for sql-interactive-mode.
754
755(defvar sql-interactive-mode-map
756  (let ((map (make-sparse-keymap)))
757    (if (fboundp 'set-keymap-parent)
758	(set-keymap-parent map comint-mode-map); Emacs
759      (if (fboundp 'set-keymap-parents)
760	  (set-keymap-parents map (list comint-mode-map)))); XEmacs
761    (if (fboundp 'set-keymap-name)
762	(set-keymap-name map 'sql-interactive-mode-map)); XEmacs
763    (define-key map (kbd "C-j") 'sql-accumulate-and-indent)
764    (define-key map (kbd "C-c C-w") 'sql-copy-column)
765    (define-key map (kbd "O") 'sql-magic-go)
766    (define-key map (kbd "o") 'sql-magic-go)
767    (define-key map (kbd ";") 'sql-magic-semicolon)
768    map)
769  "Mode map used for `sql-interactive-mode'.
770Based on `comint-mode-map'.")
771
772;; Keymap for sql-mode.
773
774(defvar sql-mode-map
775  (let ((map (make-sparse-keymap)))
776    (define-key map (kbd "C-c C-c") 'sql-send-paragraph)
777    (define-key map (kbd "C-c C-r") 'sql-send-region)
778    (define-key map (kbd "C-c C-s") 'sql-send-string)
779    (define-key map (kbd "C-c C-b") 'sql-send-buffer)
780    map)
781  "Mode map used for `sql-mode'.")
782
783;; easy menu for sql-mode.
784
785(easy-menu-define
786 sql-mode-menu sql-mode-map
787 "Menu for `sql-mode'."
788 '("SQL"
789   ["Send Paragraph" sql-send-paragraph (and (buffer-live-p sql-buffer)
790					     (get-buffer-process sql-buffer))]
791   ["Send Region" sql-send-region (and (or (and (boundp 'mark-active); Emacs
792						mark-active)
793					   (mark t)); XEmacs
794				       (buffer-live-p sql-buffer)
795				       (get-buffer-process sql-buffer))]
796   ["Send Buffer" sql-send-buffer (and (buffer-live-p sql-buffer)
797				       (get-buffer-process sql-buffer))]
798   ["Send String" sql-send-string t]
799   ["--" nil nil]
800   ["Start SQLi session" sql-product-interactive (sql-product-feature :sqli-connect)]
801   ["Show SQLi buffer" sql-show-sqli-buffer t]
802   ["Set SQLi buffer" sql-set-sqli-buffer t]
803   ["Pop to SQLi buffer after send"
804    sql-toggle-pop-to-buffer-after-send-region
805    :style toggle
806    :selected sql-pop-to-buffer-after-send-region]
807   ["--" nil nil]
808   ("Product"
809    ["ANSI" sql-highlight-ansi-keywords
810     :style radio
811     :selected (eq sql-product 'ansi)]
812    ["DB2" sql-highlight-db2-keywords
813     :style radio
814     :selected (eq sql-product 'db2)]
815    ["Informix" sql-highlight-informix-keywords
816     :style radio
817     :selected (eq sql-product 'informix)]
818    ["Ingres" sql-highlight-ingres-keywords
819     :style radio
820     :selected (eq sql-product 'ingres)]
821    ["Interbase" sql-highlight-interbase-keywords
822     :style radio
823     :selected (eq sql-product 'interbase)]
824    ["Linter" sql-highlight-linter-keywords
825     :style radio
826     :selected (eq sql-product 'linter)]
827    ["MS SQLServer" sql-highlight-ms-keywords
828     :style radio
829     :selected (eq sql-product 'ms)]
830    ["MySQL" sql-highlight-mysql-keywords
831     :style radio
832     :selected (eq sql-product 'mysql)]
833    ["Oracle" sql-highlight-oracle-keywords
834     :style radio
835     :selected (eq sql-product 'oracle)]
836    ["Postgres" sql-highlight-postgres-keywords
837     :style radio
838     :selected (eq sql-product 'postgres)]
839    ["Solid" sql-highlight-solid-keywords
840     :style radio
841     :selected (eq sql-product 'solid)]
842    ["SQLite" sql-highlight-sqlite-keywords
843     :style radio
844     :selected (eq sql-product 'sqlite)]
845    ["Sybase" sql-highlight-sybase-keywords
846     :style radio
847     :selected (eq sql-product 'sybase)]
848    )))
849
850;; easy menu for sql-interactive-mode.
851
852(easy-menu-define
853 sql-interactive-mode-menu sql-interactive-mode-map
854 "Menu for `sql-interactive-mode'."
855 '("SQL"
856   ["Rename Buffer" sql-rename-buffer t]))
857
858;; Abbreviations -- if you want more of them, define them in your
859;; ~/.emacs file.  Abbrevs have to be enabled in your ~/.emacs, too.
860
861(defvar sql-mode-abbrev-table nil
862  "Abbrev table used in `sql-mode' and `sql-interactive-mode'.")
863(unless sql-mode-abbrev-table
864  (define-abbrev-table 'sql-mode-abbrev-table nil))
865
866(mapcar
867 ;; In Emacs 22+, provide SYSTEM-FLAG to define-abbrev.
868 '(lambda (abbrev)
869    (let ((name (car abbrev))
870          (expansion (cdr abbrev)))
871      (condition-case nil
872          (define-abbrev sql-mode-abbrev-table name expansion nil 0 t)
873        (error
874         (define-abbrev sql-mode-abbrev-table name expansion)))))
875 '(("ins"  . "insert")
876   ("upd"  . "update")
877   ("del"  . "delete")
878   ("sel"  . "select")
879   ("proc" . "procedure")
880   ("func" . "function")
881   ("cr"   . "create")))
882
883;; Syntax Table
884
885(defvar sql-mode-syntax-table
886  (let ((table (make-syntax-table)))
887    ;; C-style comments /**/ (see elisp manual "Syntax Flags"))
888    (modify-syntax-entry ?/ ". 14" table)
889    (modify-syntax-entry ?* ". 23" table)
890    ;; double-dash starts comments
891    (modify-syntax-entry ?- ". 12b" table)
892    ;; newline and formfeed end comments
893    (modify-syntax-entry ?\n "> b" table)
894    (modify-syntax-entry ?\f "> b" table)
895    ;; single quotes (') delimit strings
896    (modify-syntax-entry ?' "\"" table)
897    ;; double quotes (") don't delimit strings
898    (modify-syntax-entry ?\" "." table)
899    ;; backslash is no escape character
900    (modify-syntax-entry ?\\ "." table)
901    table)
902  "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
903
904;; Font lock support
905
906(defvar sql-mode-font-lock-object-name
907  (eval-when-compile
908    (list (concat "^\\s-*\\(?:create\\|drop\\|alter\\)\\s-+" ;; lead off with CREATE, DROP or ALTER
909		  "\\(?:\\w+\\s-+\\)*"  ;; optional intervening keywords
910		  "\\(?:table\\|view\\|\\(?:package\\|type\\)\\(?:\\s-+body\\)?\\|proc\\(?:edure\\)?"
911		  "\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+"
912		  "\\(\\w+\\)")
913	  1 'font-lock-function-name-face))
914
915  "Pattern to match the names of top-level objects.
916
917The pattern matches the name in a CREATE, DROP or ALTER
918statement.  The format of variable should be a valid
919`font-lock-keywords' entry.")
920
921(defmacro sql-keywords-re (&rest keywords)
922  "Compile-time generation of regexp matching any one of KEYWORDS."
923  `(eval-when-compile
924     (concat "\\b"
925	     (regexp-opt ',keywords t)
926	     "\\b")))
927
928(defvar sql-mode-ansi-font-lock-keywords
929  (let ((ansi-funcs (sql-keywords-re
930"abs" "avg" "bit_length" "cardinality" "cast" "char_length"
931"character_length" "coalesce" "convert" "count" "current_date"
932"current_path" "current_role" "current_time" "current_timestamp"
933"current_user" "extract" "localtime" "localtimestamp" "lower" "max"
934"min" "mod" "nullif" "octet_length" "overlay" "placing" "session_user"
935"substring" "sum" "system_user" "translate" "treat" "trim" "upper"
936"user"
937))
938
939	(ansi-non-reserved (sql-keywords-re
940"ada" "asensitive" "assignment" "asymmetric" "atomic" "between"
941"bitvar" "called" "catalog_name" "chain" "character_set_catalog"
942"character_set_name" "character_set_schema" "checked" "class_origin"
943"cobol" "collation_catalog" "collation_name" "collation_schema"
944"column_name" "command_function" "command_function_code" "committed"
945"condition_number" "connection_name" "constraint_catalog"
946"constraint_name" "constraint_schema" "contains" "cursor_name"
947"datetime_interval_code" "datetime_interval_precision" "defined"
948"definer" "dispatch" "dynamic_function" "dynamic_function_code"
949"existing" "exists" "final" "fortran" "generated" "granted"
950"hierarchy" "hold" "implementation" "infix" "insensitive" "instance"
951"instantiable" "invoker" "key_member" "key_type" "length" "m"
952"message_length" "message_octet_length" "message_text" "method" "more"
953"mumps" "name" "nullable" "number" "options" "overlaps" "overriding"
954"parameter_mode" "parameter_name" "parameter_ordinal_position"
955"parameter_specific_catalog" "parameter_specific_name"
956"parameter_specific_schema" "pascal" "pli" "position" "repeatable"
957"returned_length" "returned_octet_length" "returned_sqlstate"
958"routine_catalog" "routine_name" "routine_schema" "row_count" "scale"
959"schema_name" "security" "self" "sensitive" "serializable"
960"server_name" "similar" "simple" "source" "specific_name" "style"
961"subclass_origin" "sublist" "symmetric" "system" "table_name"
962"transaction_active" "transactions_committed"
963"transactions_rolled_back" "transform" "transforms" "trigger_catalog"
964"trigger_name" "trigger_schema" "type" "uncommitted" "unnamed"
965"user_defined_type_catalog" "user_defined_type_name"
966"user_defined_type_schema"
967))
968
969	(ansi-reserved (sql-keywords-re
970"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all"
971"allocate" "alter" "and" "any" "are" "as" "asc" "assertion" "at"
972"authorization" "before" "begin" "both" "breadth" "by" "call"
973"cascade" "cascaded" "case" "catalog" "check" "class" "close"
974"collate" "collation" "column" "commit" "completion" "connect"
975"connection" "constraint" "constraints" "constructor" "continue"
976"corresponding" "create" "cross" "cube" "current" "cursor" "cycle"
977"data" "day" "deallocate" "declare" "default" "deferrable" "deferred"
978"delete" "depth" "deref" "desc" "describe" "descriptor" "destroy"
979"destructor" "deterministic" "diagnostics" "dictionary" "disconnect"
980"distinct" "domain" "drop" "dynamic" "each" "else" "end" "equals"
981"escape" "every" "except" "exception" "exec" "execute" "external"
982"false" "fetch" "first" "for" "foreign" "found" "free" "from" "full"
983"function" "general" "get" "global" "go" "goto" "grant" "group"
984"grouping" "having" "host" "hour" "identity" "ignore" "immediate" "in"
985"indicator" "initialize" "initially" "inner" "inout" "input" "insert"
986"intersect" "into" "is" "isolation" "iterate" "join" "key" "language"
987"last" "lateral" "leading" "left" "less" "level" "like" "limit"
988"local" "locator" "map" "match" "minute" "modifies" "modify" "module"
989"month" "names" "natural" "new" "next" "no" "none" "not" "null" "of"
990"off" "old" "on" "only" "open" "operation" "option" "or" "order"
991"ordinality" "out" "outer" "output" "pad" "parameter" "parameters"
992"partial" "path" "postfix" "prefix" "preorder" "prepare" "preserve"
993"primary" "prior" "privileges" "procedure" "public" "read" "reads"
994"recursive" "references" "referencing" "relative" "restrict" "result"
995"return" "returns" "revoke" "right" "role" "rollback" "rollup"
996"routine" "rows" "savepoint" "schema" "scroll" "search" "second"
997"section" "select" "sequence" "session" "set" "sets" "size" "some"
998"space" "specific" "specifictype" "sql" "sqlexception" "sqlstate"
999"sqlwarning" "start" "state" "statement" "static" "structure" "table"
1000"temporary" "terminate" "than" "then" "timezone_hour"
1001"timezone_minute" "to" "trailing" "transaction" "translation"
1002"trigger" "true" "under" "union" "unique" "unknown" "unnest" "update"
1003"usage" "using" "value" "values" "variable" "view" "when" "whenever"
1004"where" "with" "without" "work" "write" "year"
1005))
1006
1007	(ansi-types (sql-keywords-re
1008"array" "binary" "bit" "blob" "boolean" "char" "character" "clob"
1009"date" "dec" "decimal" "double" "float" "int" "integer" "interval"
1010"large" "national" "nchar" "nclob" "numeric" "object" "precision"
1011"real" "ref" "row" "scope" "smallint" "time" "timestamp" "varchar"
1012"varying" "zone"
1013)))
1014
1015    `((,ansi-non-reserved . font-lock-keyword-face)
1016      (,ansi-reserved     . font-lock-keyword-face)
1017      (,ansi-funcs        . font-lock-builtin-face)
1018      (,ansi-types        . font-lock-type-face)))
1019
1020  "ANSI SQL keywords used by font-lock.
1021
1022This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1023regular expressions are created during compilation by calling the
1024function `regexp-opt'.  Therefore, take a look at the source before
1025you define your own sql-mode-ansi-font-lock-keywords.  You may want to
1026add functions and PL/SQL keywords.")
1027
1028(defvar sql-mode-oracle-font-lock-keywords
1029  (let ((oracle-functions (sql-keywords-re
1030"abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2"
1031"avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid"
1032"chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh"
1033"count" "covar_pop" "covar_samp" "cume_dist" "current_date"
1034"current_timestamp" "current_user" "dbtimezone" "decode" "decompose"
1035"dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp"
1036"extract" "extractvalue" "first" "first_value" "floor" "following"
1037"from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap"
1038"instr" "lag" "last" "last_day" "last_value" "lead" "least" "length"
1039"ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min"
1040"mod" "months_between" "new_time" "next_day" "nls_charset_decl_len"
1041"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower"
1042"nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval"
1043"numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank"
1044"percentile_cont" "percentile_disc" "power" "preceding" "rank"
1045"ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_"
1046"regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2"
1047"regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round"
1048"row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim"
1049"sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev"
1050"stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path"
1051"sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid"
1052"sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh"
1053"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
1054"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
1055"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
1056"tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user"
1057"userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml"
1058"xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement"
1059"xmlforest" "xmlsequence" "xmltransform"
1060))
1061
1062	(oracle-keywords (sql-keywords-re
1063"abort" "access" "accessed" "account" "activate" "add" "admin"
1064"advise" "after" "agent" "aggregate" "all" "allocate" "allow" "alter"
1065"always" "analyze" "ancillary" "and" "any" "apply" "archive"
1066"archivelog" "array" "as" "asc" "associate" "at" "attribute"
1067"attributes" "audit" "authenticated" "authid" "authorization" "auto"
1068"autoallocate" "automatic" "availability" "backup" "before" "begin"
1069"behalf" "between" "binding" "bitmap" "block" "blocksize" "body"
1070"both" "buffer_pool" "build" "by"  "cache" "call" "cancel"
1071"cascade" "case" "category" "certificate" "chained" "change" "check"
1072"checkpoint" "child" "chunk" "class" "clear" "clone" "close" "cluster"
1073"column" "column_value" "columns" "comment" "commit" "committed"
1074"compatibility" "compile" "complete" "composite_limit" "compress"
1075"compute" "connect" "connect_time" "consider" "consistent"
1076"constraint" "constraints" "constructor" "contents" "context"
1077"continue" "controlfile" "corruption" "cost" "cpu_per_call"
1078"cpu_per_session" "create" "cross" "cube" "current" "currval" "cycle"
1079"dangling" "data" "database" "datafile" "datafiles" "day" "ddl"
1080"deallocate" "debug" "default" "deferrable" "deferred" "definer"
1081"delay" "delete" "demand" "desc" "determines" "deterministic"
1082"dictionary" "dimension" "directory" "disable" "disassociate"
1083"disconnect" "distinct" "distinguished" "distributed" "dml" "drop"
1084"each" "element" "else" "enable" "end" "equals_path" "escape"
1085"estimate" "except" "exceptions" "exchange" "excluding" "exists"
1086"expire" "explain" "extent" "external" "externally"
1087"failed_login_attempts" "fast" "file" "final" "finish" "flush" "for"
1088"force" "foreign" "freelist" "freelists" "freepools" "fresh" "from"
1089"full" "function" "functions" "generated" "global" "global_name"
1090"globally" "grant" "group" "grouping" "groups" "guard" "hash"
1091"hashkeys" "having" "heap" "hierarchy" "id" "identified" "identifier"
1092"idle_time" "immediate" "in" "including" "increment" "index" "indexed"
1093"indexes" "indextype" "indextypes" "indicator" "initial" "initialized"
1094"initially" "initrans" "inner" "insert" "instance" "instantiable"
1095"instead" "intersect" "into" "invalidate" "is" "isolation" "java"
1096"join"  "keep" "key" "kill" "language" "left" "less" "level"
1097"levels" "library" "like" "like2" "like4" "likec" "limit" "link"
1098"list" "lob" "local" "location" "locator" "lock" "log" "logfile"
1099"logging" "logical" "logical_reads_per_call"
1100"logical_reads_per_session"  "managed" "management" "manual" "map"
1101"mapping" "master" "matched" "materialized" "maxdatafiles"
1102"maxextents" "maximize" "maxinstances" "maxlogfiles" "maxloghistory"
1103"maxlogmembers" "maxsize" "maxtrans" "maxvalue" "member" "memory"
1104"merge" "migrate" "minextents" "minimize" "minimum" "minus" "minvalue"
1105"mode" "modify" "monitoring" "month" "mount" "move" "movement" "name"
1106"named" "natural" "nested" "never" "new" "next" "nextval" "no"
1107"noarchivelog" "noaudit" "nocache" "nocompress" "nocopy" "nocycle"
1108"nodelay" "noforce" "nologging" "nomapping" "nomaxvalue" "nominimize"
1109"nominvalue" "nomonitoring" "none" "noorder" "noparallel" "norely"
1110"noresetlogs" "noreverse" "normal" "norowdependencies" "nosort"
1111"noswitch" "not" "nothing" "notimeout" "novalidate" "nowait" "null"
1112"nulls" "object" "of" "off" "offline" "oidindex" "old" "on" "online"
1113"only" "open" "operator" "optimal" "option" "or" "order"
1114"organization" "out" "outer" "outline" "overflow" "overriding"
1115"package" "packages" "parallel" "parallel_enable" "parameters"
1116"parent" "partition" "partitions" "password" "password_grace_time"
1117"password_life_time" "password_lock_time" "password_reuse_max"
1118"password_reuse_time" "password_verify_function" "pctfree"
1119"pctincrease" "pctthreshold" "pctused" "pctversion" "percent"
1120"performance" "permanent" "pfile" "physical" "pipelined" "plan"
1121"post_transaction" "pragma" "prebuilt" "preserve" "primary" "private"
1122"private_sga" "privileges" "procedure" "profile" "protection" "public"
1123"purge" "query" "quiesce" "quota" "range" "read" "reads" "rebuild"
1124"records_per_block" "recover" "recovery" "recycle" "reduced" "ref"
1125"references" "referencing" "refresh" "register" "reject" "relational"
1126"rely" "rename" "reset" "resetlogs" "resize" "resolve" "resolver"
1127"resource" "restrict" "restrict_references" "restricted" "result"
1128"resumable" "resume" "retention" "return" "returning" "reuse"
1129"reverse" "revoke" "rewrite" "right" "rnds" "rnps" "role" "roles"
1130"rollback" "rollup" "row" "rowdependencies" "rownum" "rows" "sample"
1131"savepoint" "scan" "schema" "scn" "scope" "segment" "select"
1132"selectivity" "self" "sequence" "serializable" "session"
1133"sessions_per_user" "set" "sets" "settings" "shared" "shared_pool"
1134"shrink" "shutdown" "siblings" "sid" "single" "size" "skip" "some"
1135"sort" "source" "space" "specification" "spfile" "split" "standby"
1136"start" "statement_id" "static" "statistics" "stop" "storage" "store"
1137"structure" "subpartition" "subpartitions" "substitutable"
1138"successful" "supplemental" "suspend" "switch" "switchover" "synonym"
1139"sys" "system" "table" "tables" "tablespace" "tempfile" "template"
1140"temporary" "test" "than" "then" "thread" "through" "time_zone"
1141"timeout" "to" "trace" "transaction" "trigger" "triggers" "truncate"
1142"trust" "type" "types" "unarchived" "under" "under_path" "undo"
1143"uniform" "union" "unique" "unlimited" "unlock" "unquiesce"
1144"unrecoverable" "until" "unusable" "unused" "update" "upgrade" "usage"
1145"use" "using" "validate" "validation" "value" "values" "variable"
1146"varray" "version" "view" "wait" "when" "whenever" "where" "with"
1147"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype"
1148))
1149
1150	(oracle-types (sql-keywords-re
1151"bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal"
1152"double" "float" "int" "integer" "interval" "long" "national" "nchar"
1153"nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real"
1154"rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar"
1155"varchar2" "varying" "year" "zone"
1156))
1157
1158	(plsql-functions (sql-keywords-re
1159"%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype"
1160"%type" "extend" "prior"
1161))
1162
1163	(plsql-keywords (sql-keywords-re
1164"autonomous_transaction" "bulk" "char_base" "collect" "constant"
1165"cursor" "declare" "do" "elsif" "exception_init" "execute" "exit"
1166"extends" "false" "fetch" "forall" "goto" "hour" "if" "interface"
1167"loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype"
1168"separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype"
1169"the" "timezone_abbr" "timezone_hour" "timezone_minute"
1170"timezone_region" "true" "varrying" "while"
1171))
1172
1173	(plsql-type (sql-keywords-re
1174"binary_integer" "boolean" "naturaln" "pls_integer" "positive"
1175"positiven" "record" "signtype" "string"
1176))
1177
1178	(plsql-warning (sql-keywords-re
1179"access_into_null" "case_not_found" "collection_is_null"
1180"cursor_already_open" "dup_val_on_index" "invalid_cursor"
1181"invalid_number" "login_denied" "no_data_found" "not_logged_on"
1182"program_error" "rowtype_mismatch" "self_is_null" "storage_error"
1183"subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid"
1184"timeout_on_resource" "too_many_rows" "value_error" "zero_divide"
1185"exception" "notfound"
1186))
1187
1188	(sqlplus-commands
1189	 (eval-when-compile (concat "^\\(\\("
1190				    (regexp-opt '(
1191"@" "@@" "accept" "append" "archive" "attribute" "break"
1192"btitle" "change" "clear" "column" "connect" "copy" "define"
1193"del" "describe" "disconnect" "edit" "execute" "exit" "get" "help"
1194"host" "input" "list" "password" "pause" "print" "prompt" "recover"
1195"remark" "repfooter" "repheader" "run" "save" "show" "shutdown"
1196"spool" "start" "startup" "store" "timing" "ttitle" "undefine"
1197"variable" "whenever"
1198
1199) t)
1200
1201   "\\)\\|"
1202   "\\(compute\\s-+\\(avg\\|cou\\|min\\|max\\|num\\|sum\\|std\\|var\\)\\)\\|"
1203   "\\(set\\s-+\\(appi\\(nfo\\)?\\|array\\(size\\)?\\|"
1204   "auto\\(commit\\)?\\|autop\\(rint\\)?\\|autorecovery\\|"
1205   "autot\\(race\\)?\\|blo\\(ckterminator\\)?\\|cmds\\(ep\\)?\\|"
1206   "colsep\\|com\\(patibility\\)?\\|con\\(cat\\)?\\|"
1207   "copyc\\(ommit\\)?\\|copytypecheck\\|def\\(ine\\)?\\|"
1208   "describe\\|echo\\|editf\\(ile\\)?\\|emb\\(edded\\)?\\|"
1209   "esc\\(ape\\)?\\|feed\\(back\\)?\\|flagger\\|"
1210   "flu\\(sh\\)?\\|hea\\(ding\\)?\\|heads\\(ep\\)?\\|"
1211   "instance\\|lin\\(esize\\)?\\|lobof\\(fset\\)?\\|"
1212   "logsource\\|long\\|longc\\(hunksize\\)?\\|mark\\(up\\)?\\|"
1213   "newp\\(age\\)?\\|null\\|numf\\(ormat\\)?\\|"
1214   "num\\(width\\)?\\|pages\\(ize\\)?\\|pau\\(se\\)?\\|"
1215   "recsep\\|recsepchar\\|serverout\\(put\\)?\\|"
1216   "shift\\(inout\\)?\\|show\\(mode\\)?\\|"
1217   "sqlbl\\(anklines\\)?\\|sqlc\\(ase\\)?\\|"
1218   "sqlco\\(ntinue\\)?\\|sqln\\(umber\\)?\\|"
1219   "sqlpluscompat\\(ibility\\)?\\|sqlpre\\(fix\\)?\\|"
1220   "sqlp\\(rompt\\)?\\|sqlt\\(erminator\\)?\\|"
1221   "suf\\(fix\\)?\\|tab\\|term\\(out\\)?\\|ti\\(me\\)?\\|"
1222   "timi\\(ng\\)?\\|trim\\(out\\)?\\|trims\\(pool\\)?\\|"
1223   "und\\(erline\\)?\\|ver\\(ify\\)?\\|wra\\(p\\)?\\)\\)\\)"
1224   "\\b.*$"
1225   ))))
1226
1227    `((,sqlplus-commands . font-lock-doc-face)
1228      (,oracle-functions . font-lock-builtin-face)
1229      (,oracle-keywords  . font-lock-keyword-face)
1230      (,oracle-types     . font-lock-type-face)
1231      (,plsql-functions  . font-lock-builtin-face)
1232      (,plsql-keywords   . font-lock-keyword-face)
1233      (,plsql-type       . font-lock-type-face)
1234      (,plsql-warning    . font-lock-warning-face)))
1235
1236  "Oracle SQL keywords used by font-lock.
1237
1238This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1239regular expressions are created during compilation by calling the
1240function `regexp-opt'.  Therefore, take a look at the source before
1241you define your own sql-mode-oracle-font-lock-keywords.  You may want
1242to add functions and PL/SQL keywords.")
1243
1244(defvar sql-mode-postgres-font-lock-keywords
1245  (let ((pg-funcs (sql-keywords-re
1246"abbrev" "abs" "acos" "age" "area" "ascii" "asin" "atab2" "atan"
1247"atan2" "avg" "bit_length" "both" "broadcast" "btrim" "cbrt" "ceil"
1248"center" "char_length" "chr" "coalesce" "col_description" "convert"
1249"cos" "cot" "count" "current_database" "current_date" "current_schema"
1250"current_schemas" "current_setting" "current_time" "current_timestamp"
1251"current_user" "currval" "date_part" "date_trunc" "decode" "degrees"
1252"diameter" "encode" "exp" "extract" "floor" "get_bit" "get_byte"
1253"has_database_privilege" "has_function_privilege"
1254"has_language_privilege" "has_schema_privilege" "has_table_privilege"
1255"height" "host" "initcap" "isclosed" "isfinite" "isopen" "leading"
1256"length" "ln" "localtime" "localtimestamp" "log" "lower" "lpad"
1257"ltrim" "masklen" "max" "min" "mod" "netmask" "network" "nextval"
1258"now" "npoints" "nullif" "obj_description" "octet_length" "overlay"
1259"pclose" "pg_client_encoding" "pg_function_is_visible"
1260"pg_get_constraintdef" "pg_get_indexdef" "pg_get_ruledef"
1261"pg_get_userbyid" "pg_get_viewdef" "pg_opclass_is_visible"
1262"pg_operator_is_visible" "pg_table_is_visible" "pg_type_is_visible"
1263"pi" "popen" "position" "pow" "quote_ident" "quote_literal" "radians"
1264"radius" "random" "repeat" "replace" "round" "rpad" "rtrim"
1265"session_user" "set_bit" "set_byte" "set_config" "set_masklen"
1266"setval" "sign" "sin" "split_part" "sqrt" "stddev" "strpos" "substr"
1267"substring" "sum" "tan" "timeofday" "to_ascii" "to_char" "to_date"
1268"to_hex" "to_number" "to_timestamp" "trailing" "translate" "trim"
1269"trunc" "upper" "variance" "version" "width"
1270))
1271
1272	(pg-reserved (sql-keywords-re
1273"abort" "access" "add" "after" "aggregate" "alignment" "all" "alter"
1274"analyze" "and" "any" "as" "asc" "assignment" "authorization"
1275"backward" "basetype" "before" "begin" "between" "binary" "by" "cache"
1276"called" "cascade" "case" "cast" "characteristics" "check"
1277"checkpoint" "class" "close" "cluster" "column" "comment" "commit"
1278"committed" "commutator" "constraint" "constraints" "conversion"
1279"copy" "create" "createdb" "createuser" "cursor" "cycle" "database"
1280"deallocate" "declare" "default" "deferrable" "deferred" "definer"
1281"delete" "delimiter" "desc" "distinct" "do" "domain" "drop" "each"
1282"element" "else" "encoding" "encrypted" "end" "escape" "except"
1283"exclusive" "execute" "exists" "explain" "extended" "external" "false"
1284"fetch" "finalfunc" "for" "force" "foreign" "forward" "freeze" "from"
1285"full" "function" "grant" "group" "gtcmp" "handler" "hashes" "having"
1286"immediate" "immutable" "implicit" "in" "increment" "index" "inherits"
1287"initcond" "initially" "input" "insensitive" "insert" "instead"
1288"internallength" "intersect" "into" "invoker" "is" "isnull"
1289"isolation" "join" "key" "language" "leftarg" "level" "like" "limit"
1290"listen" "load" "local" "location" "lock" "ltcmp" "main" "match"
1291"maxvalue" "merges" "minvalue" "mode" "move" "natural" "negator"
1292"next" "nocreatedb" "nocreateuser" "none" "not" "nothing" "notify"
1293"notnull" "null" "of" "offset" "oids" "on" "only" "operator" "or"
1294"order" "output" "owner" "partial" "passedbyvalue" "password" "plain"
1295"prepare" "primary" "prior" "privileges" "procedural" "procedure"
1296"public" "read" "recheck" "references" "reindex" "relative" "rename"
1297"reset" "restrict" "returns" "revoke" "rightarg" "rollback" "row"
1298"rule" "schema" "scroll" "security" "select" "sequence" "serializable"
1299"session" "set" "sfunc" "share" "show" "similar" "some" "sort1"
1300"sort2" "stable" "start" "statement" "statistics" "storage" "strict"
1301"stype" "sysid" "table" "temp" "template" "temporary" "then" "to"
1302"transaction" "trigger" "true" "truncate" "trusted" "type"
1303"unencrypted" "union" "unique" "unknown" "unlisten" "until" "update"
1304"usage" "user" "using" "vacuum" "valid" "validator" "values"
1305"variable" "verbose" "view" "volatile" "when" "where" "with" "without"
1306"work"
1307))
1308
1309	(pg-types (sql-keywords-re
1310"anyarray" "bigint" "bigserial" "bit" "boolean" "box" "bytea" "char"
1311"character" "cidr" "circle" "cstring" "date" "decimal" "double"
1312"float4" "float8" "inet" "int2" "int4" "int8" "integer" "internal"
1313"interval" "language_handler" "line" "lseg" "macaddr" "money"
1314"numeric" "oid" "opaque" "path" "point" "polygon" "precision" "real"
1315"record" "regclass" "regoper" "regoperator" "regproc" "regprocedure"
1316"regtype" "serial" "serial4" "serial8" "smallint" "text" "time"
1317"timestamp" "varchar" "varying" "void" "zone"
1318)))
1319
1320  `((,pg-funcs    . font-lock-builtin-face)
1321    (,pg-reserved . font-lock-keyword-face)
1322    (,pg-types    . font-lock-type-face)))
1323
1324  "Postgres SQL keywords used by font-lock.
1325
1326This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1327regular expressions are created during compilation by calling the
1328function `regexp-opt'.  Therefore, take a look at the source before
1329you define your own sql-mode-postgres-font-lock-keywords.")
1330
1331(defvar sql-mode-linter-font-lock-keywords
1332  (let ((linter-keywords (sql-keywords-re
1333"autocommit" "autoinc" "autorowid" "cancel" "cascade" "channel"
1334"committed" "count" "countblob" "cross" "current" "data" "database"
1335"datafile" "datafiles" "datesplit" "dba" "dbname" "default" "deferred"
1336"denied" "description" "device" "difference" "directory" "error"
1337"escape" "euc" "exclusive" "external" "extfile" "false" "file"
1338"filename" "filesize" "filetime" "filter" "findblob" "first" "foreign"
1339"full" "fuzzy" "global" "granted" "ignore" "immediate" "increment"
1340"indexes" "indexfile" "indexfiles" "indextime" "initial" "integrity"
1341"internal" "key" "last_autoinc" "last_rowid" "limit" "linter"
1342"linter_file_device" "linter_file_size" "linter_name_length" "ln"
1343"local" "login" "maxisn" "maxrow" "maxrowid" "maxvalue" "message"
1344"minvalue" "module" "names" "national" "natural" "new" "new_table"
1345"no" "node" "noneuc" "nulliferror" "numbers" "off" "old" "old_table"
1346"only" "operation" "optimistic" "option" "page" "partially" "password"
1347"phrase" "plan" "precision" "primary" "priority" "privileges"
1348"proc_info_size" "proc_par_name_len" "protocol" "quant" "range" "raw"
1349"read" "record" "records" "references" "remote" "rename" "replication"
1350"restart" "rewrite" "root" "row" "rule" "savepoint" "security"
1351"sensitive" "sequence" "serializable" "server" "since" "size" "some"
1352"startup" "statement" "station" "success" "sys_guid" "tables" "test"
1353"timeout" "trace" "transaction" "translation" "trigger"
1354"trigger_info_size" "true" "trunc" "uncommitted" "unicode" "unknown"
1355"unlimited" "unlisted" "user" "utf8" "value" "varying" "volumes"
1356"wait" "windows_code" "workspace" "write" "xml"
1357))
1358
1359	(linter-reserved (sql-keywords-re
1360"access" "action" "add" "address" "after" "all" "alter" "always" "and"
1361"any" "append" "as" "asc" "ascic" "async" "at_begin" "at_end" "audit"
1362"aud_obj_name_len" "backup" "base" "before" "between" "blobfile"
1363"blobfiles" "blobpct" "brief" "browse" "by" "case" "cast" "check"
1364"clear" "close" "column" "comment" "commit" "connect" "contains"
1365"correct" "create" "delete" "desc" "disable" "disconnect" "distinct"
1366"drop" "each" "ef" "else" "enable" "end" "event" "except" "exclude"
1367"execute" "exists" "extract" "fetch" "finish" "for" "from" "get"
1368"grant" "group" "having" "identified" "in" "index" "inner" "insert"
1369"instead" "intersect" "into" "is" "isolation" "join" "left" "level"
1370"like" "lock" "mode" "modify" "not" "nowait" "null" "of" "on" "open"
1371"or" "order" "outer" "owner" "press" "prior" "procedure" "public"
1372"purge" "rebuild" "resource" "restrict" "revoke" "right" "role"
1373"rollback" "rownum" "select" "session" "set" "share" "shutdown"
1374"start" "stop" "sync" "synchronize" "synonym" "sysdate" "table" "then"
1375"to" "union" "unique" "unlock" "until" "update" "using" "values"
1376"view" "when" "where" "with" "without"
1377))
1378
1379	(linter-types (sql-keywords-re
1380"bigint" "bitmap" "blob" "boolean" "char" "character" "date"
1381"datetime" "dec" "decimal" "double" "float" "int" "integer" "nchar"
1382"number" "numeric" "real" "smallint" "varbyte" "varchar" "byte"
1383"cursor" "long"
1384))
1385
1386	(linter-functions (sql-keywords-re
1387"abs" "acos" "asin" "atan" "atan2" "avg" "ceil" "cos" "cosh" "divtime"
1388"exp" "floor" "getbits" "getblob" "getbyte" "getlong" "getraw"
1389"getstr" "gettext" "getword" "hextoraw" "lenblob" "length" "log"
1390"lower" "lpad" "ltrim" "max" "min" "mod" "monthname" "nvl"
1391"octet_length" "power" "rand" "rawtohex" "repeat_string"
1392"right_substr" "round" "rpad" "rtrim" "sign" "sin" "sinh" "soundex"
1393"sqrt" "sum" "tan" "tanh" "timeint_to_days" "to_char" "to_date"
1394"to_gmtime" "to_localtime" "to_number" "trim" "upper" "decode"
1395"substr" "substring" "chr" "dayname" "days" "greatest" "hex" "initcap"
1396"instr" "least" "multime" "replace" "width"
1397)))
1398
1399    `((,linter-keywords  . font-lock-keyword-face)
1400      (,linter-reserved  . font-lock-keyword-face)
1401      (,linter-functions . font-lock-builtin-face)
1402      (,linter-types     . font-lock-type-face)))
1403
1404  "Linter SQL keywords used by font-lock.
1405
1406This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1407regular expressions are created during compilation by calling the
1408function `regexp-opt'.")
1409
1410(defvar sql-mode-ms-font-lock-keywords
1411  (let ((ms-reserved (sql-keywords-re
1412"absolute" "add" "all" "alter" "and" "any" "as" "asc" "authorization"
1413"avg" "backup" "begin" "between" "break" "browse" "bulk" "by"
1414"cascade" "case" "check" "checkpoint" "close" "clustered" "coalesce"
1415"column" "commit" "committed" "compute" "confirm" "constraint"
1416"contains" "containstable" "continue" "controlrow" "convert" "count"
1417"create" "cross" "current" "current_date" "current_time"
1418"current_timestamp" "current_user" "database" "deallocate" "declare"
1419"default" "delete" "deny" "desc" "disk" "distinct" "distributed"
1420"double" "drop" "dummy" "dump" "else" "end" "errlvl" "errorexit"
1421"escape" "except" "exec" "execute" "exists" "exit" "fetch" "file"
1422"fillfactor" "first" "floppy" "for" "foreign" "freetext"
1423"freetexttable" "from" "full" "goto" "grant" "group" "having"
1424"holdlock" "identity" "identity_insert" "identitycol" "if" "in"
1425"index" "inner" "insert" "intersect" "into" "is" "isolation" "join"
1426"key" "kill" "last" "left" "level" "like" "lineno" "load" "max" "min"
1427"mirrorexit" "national" "next" "nocheck" "nolock" "nonclustered" "not"
1428"null" "nullif" "of" "off" "offsets" "on" "once" "only" "open"
1429"opendatasource" "openquery" "openrowset" "option" "or" "order"
1430"outer" "output" "over" "paglock" "percent" "perm" "permanent" "pipe"
1431"plan" "precision" "prepare" "primary" "print" "prior" "privileges"
1432"proc" "procedure" "processexit" "public" "raiserror" "read"
1433"readcommitted" "readpast" "readtext" "readuncommitted" "reconfigure"
1434"references" "relative" "repeatable" "repeatableread" "replication"
1435"restore" "restrict" "return" "revoke" "right" "rollback" "rowcount"
1436"rowguidcol" "rowlock" "rule" "save" "schema" "select" "serializable"
1437"session_user" "set" "shutdown" "some" "statistics" "sum"
1438"system_user" "table" "tablock" "tablockx" "tape" "temp" "temporary"
1439"textsize" "then" "to" "top" "tran" "transaction" "trigger" "truncate"
1440"tsequal" "uncommitted" "union" "unique" "update" "updatetext"
1441"updlock" "use" "user" "values" "view" "waitfor" "when" "where"
1442"while" "with" "work" "writetext" "collate" "function" "openxml"
1443"returns"
1444))
1445
1446	(ms-types (sql-keywords-re
1447"binary" "bit" "char" "character" "cursor" "datetime" "dec" "decimal"
1448"double" "float" "image" "int" "integer" "money" "national" "nchar"
1449"ntext" "numeric" "numeric" "nvarchar" "precision" "real"
1450"smalldatetime" "smallint" "smallmoney" "text" "timestamp" "tinyint"
1451"uniqueidentifier" "varbinary" "varchar" "varying"
1452))
1453
1454	(ms-vars "\\b@[a-zA-Z0-9_]*\\b")
1455
1456	(ms-functions (sql-keywords-re
1457"@@connections" "@@cpu_busy" "@@cursor_rows" "@@datefirst" "@@dbts"
1458"@@error" "@@fetch_status" "@@identity" "@@idle" "@@io_busy"
1459"@@langid" "@@language" "@@lock_timeout" "@@max_connections"
1460"@@max_precision" "@@nestlevel" "@@options" "@@pack_received"
1461"@@pack_sent" "@@packet_errors" "@@procid" "@@remserver" "@@rowcount"
1462"@@servername" "@@servicename" "@@spid" "@@textsize" "@@timeticks"
1463"@@total_errors" "@@total_read" "@@total_write" "@@trancount"
1464"@@version" "abs" "acos" "and" "app_name" "ascii" "asin" "atan" "atn2"
1465"avg" "case" "cast" "ceiling" "char" "charindex" "coalesce"
1466"col_length" "col_name" "columnproperty" "containstable" "convert"
1467"cos" "cot" "count" "current_timestamp" "current_user" "cursor_status"
1468"databaseproperty" "datalength" "dateadd" "datediff" "datename"
1469"datepart" "day" "db_id" "db_name" "degrees" "difference" "exp"
1470"file_id" "file_name" "filegroup_id" "filegroup_name"
1471"filegroupproperty" "fileproperty" "floor" "formatmessage"
1472"freetexttable" "fulltextcatalogproperty" "fulltextserviceproperty"
1473"getansinull" "getdate" "grouping" "host_id" "host_name" "ident_incr"
1474"ident_seed" "identity" "index_col" "indexproperty" "is_member"
1475"is_srvrolemember" "isdate" "isnull" "isnumeric" "left" "len" "log"
1476"log10" "lower" "ltrim" "max" "min" "month" "nchar" "newid" "nullif"
1477"object_id" "object_name" "objectproperty" "openquery" "openrowset"
1478"parsename" "patindex" "patindex" "permissions" "pi" "power"
1479"quotename" "radians" "rand" "replace" "replicate" "reverse" "right"
1480"round" "rtrim" "session_user" "sign" "sin" "soundex" "space" "sqrt"
1481"square" "stats_date" "stdev" "stdevp" "str" "stuff" "substring" "sum"
1482"suser_id" "suser_name" "suser_sid" "suser_sname" "system_user" "tan"
1483"textptr" "textvalid" "typeproperty" "unicode" "upper" "user"
1484"user_id" "user_name" "var" "varp" "year"
1485))
1486
1487	(ms-commands
1488	 (eval-when-compile
1489	   (concat "^\\(\\(set\\s-+\\("
1490		   (regexp-opt '(
1491"datefirst" "dateformat" "deadlock_priority" "lock_timeout"
1492"concat_null_yields_null" "cursor_close_on_commit"
1493"disable_def_cnst_chk" "fips_flagger" "identity_insert" "language"
1494"offsets" "quoted_identifier" "arithabort" "arithignore" "fmtonly"
1495"nocount" "noexec" "numeric_roundabort" "parseonly"
1496"query_governor_cost_limit" "rowcount" "textsize" "ansi_defaults"
1497"ansi_null_dflt_off" "ansi_null_dflt_on" "ansi_nulls" "ansi_padding"
1498"ansi_warnings" "forceplan" "showplan_all" "showplan_text"
1499"statistics" "implicit_transactions" "remote_proc_transactions"
1500"transaction" "xact_abort"
1501) t)
1502		   "\\)\\)\\|go\\s-*\\|use\\s-+\\|setuser\\s-+\\|dbcc\\s-+\\).*$"))))
1503
1504    `((,ms-commands  . font-lock-doc-face)
1505      (,ms-reserved  . font-lock-keyword-face)
1506      (,ms-functions . font-lock-builtin-face)
1507      (,ms-vars      . font-lock-variable-name-face)
1508      (,ms-types     . font-lock-type-face)))
1509
1510  "Microsoft SQLServer SQL keywords used by font-lock.
1511
1512This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1513regular expressions are created during compilation by calling the
1514function `regexp-opt'.  Therefore, take a look at the source before
1515you define your own sql-mode-ms-font-lock-keywords.")
1516
1517(defvar sql-mode-sybase-font-lock-keywords nil
1518  "Sybase SQL keywords used by font-lock.
1519
1520This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1521regular expressions are created during compilation by calling the
1522function `regexp-opt'.  Therefore, take a look at the source before
1523you define your own sql-mode-sybase-font-lock-keywords.")
1524
1525(defvar sql-mode-informix-font-lock-keywords nil
1526  "Informix SQL keywords used by font-lock.
1527
1528This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1529regular expressions are created during compilation by calling the
1530function `regexp-opt'.  Therefore, take a look at the source before
1531you define your own sql-mode-informix-font-lock-keywords.")
1532
1533(defvar sql-mode-interbase-font-lock-keywords nil
1534  "Interbase SQL keywords used by font-lock.
1535
1536This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1537regular expressions are created during compilation by calling the
1538function `regexp-opt'.  Therefore, take a look at the source before
1539you define your own sql-mode-interbase-font-lock-keywords.")
1540
1541(defvar sql-mode-ingres-font-lock-keywords nil
1542  "Ingres SQL keywords used by font-lock.
1543
1544This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1545regular expressions are created during compilation by calling the
1546function `regexp-opt'.  Therefore, take a look at the source before
1547you define your own sql-mode-interbase-font-lock-keywords.")
1548
1549(defvar sql-mode-solid-font-lock-keywords nil
1550  "Solid SQL keywords used by font-lock.
1551
1552This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1553regular expressions are created during compilation by calling the
1554function `regexp-opt'.  Therefore, take a look at the source before
1555you define your own sql-mode-solid-font-lock-keywords.")
1556
1557(defvar sql-mode-mysql-font-lock-keywords
1558  (let ((mysql-funcs (sql-keywords-re
1559"ascii" "avg" "bdmpolyfromtext" "bdmpolyfromwkb" "bdpolyfromtext"
1560"bdpolyfromwkb" "benchmark" "bin" "bit_and" "bit_length" "bit_or"
1561"bit_xor" "both" "cast" "char_length" "character_length" "coalesce"
1562"concat" "concat_ws" "connection_id" "conv" "convert" "count"
1563"curdate" "current_date" "current_time" "current_timestamp" "curtime"
1564"elt" "encrypt" "export_set" "field" "find_in_set" "found_rows" "from"
1565"geomcollfromtext" "geomcollfromwkb" "geometrycollectionfromtext"
1566"geometrycollectionfromwkb" "geometryfromtext" "geometryfromwkb"
1567"geomfromtext" "geomfromwkb" "get_lock" "group_concat" "hex" "ifnull"
1568"instr" "interval" "isnull" "last_insert_id" "lcase" "leading"
1569"length" "linefromtext" "linefromwkb" "linestringfromtext"
1570"linestringfromwkb" "load_file" "locate" "lower" "lpad" "ltrim"
1571"make_set" "master_pos_wait" "max" "mid" "min" "mlinefromtext"
1572"mlinefromwkb" "mpointfromtext" "mpointfromwkb" "mpolyfromtext"
1573"mpolyfromwkb" "multilinestringfromtext" "multilinestringfromwkb"
1574"multipointfromtext" "multipointfromwkb" "multipolygonfromtext"
1575"multipolygonfromwkb" "now" "nullif" "oct" "octet_length" "ord"
1576"pointfromtext" "pointfromwkb" "polyfromtext" "polyfromwkb"
1577"polygonfromtext" "polygonfromwkb" "position" "quote" "rand"
1578"release_lock" "repeat" "replace" "reverse" "rpad" "rtrim" "soundex"
1579"space" "std" "stddev" "substring" "substring_index" "sum" "sysdate"
1580"trailing" "trim" "ucase" "unix_timestamp" "upper" "user" "variance"
1581))
1582
1583	(mysql-keywords (sql-keywords-re
1584"action" "add" "after" "against" "all" "alter" "and" "as" "asc"
1585"auto_increment" "avg_row_length" "bdb" "between" "by" "cascade"
1586"case" "change" "character" "check" "checksum" "close" "collate"
1587"collation" "column" "columns" "comment" "committed" "concurrent"
1588"constraint" "create" "cross" "data" "database" "default"
1589"delay_key_write" "delayed" "delete" "desc" "directory" "disable"
1590"distinct" "distinctrow" "do" "drop" "dumpfile" "duplicate" "else"
1591"enable" "enclosed" "end" "escaped" "exists" "fields" "first" "for"
1592"force" "foreign" "from" "full" "fulltext" "global" "group" "handler"
1593"having" "heap" "high_priority" "if" "ignore" "in" "index" "infile"
1594"inner" "insert" "insert_method" "into" "is" "isam" "isolation" "join"
1595"key" "keys" "last" "left" "level" "like" "limit" "lines" "load"
1596"local" "lock" "low_priority" "match" "max_rows" "merge" "min_rows"
1597"mode" "modify" "mrg_myisam" "myisam" "natural" "next" "no" "not"
1598"null" "offset" "oj" "on" "open" "optionally" "or" "order" "outer"
1599"outfile" "pack_keys" "partial" "password" "prev" "primary"
1600"procedure" "quick" "raid0" "raid_type" "read" "references" "rename"
1601"repeatable" "restrict" "right" "rollback" "rollup" "row_format"
1602"savepoint" "select" "separator" "serializable" "session" "set"
1603"share" "show" "sql_big_result" "sql_buffer_result" "sql_cache"
1604"sql_calc_found_rows" "sql_no_cache" "sql_small_result" "starting"
1605"straight_join" "striped" "table" "tables" "temporary" "terminated"
1606"then" "to" "transaction" "truncate" "type" "uncommitted" "union"
1607"unique" "unlock" "update" "use" "using" "values" "when" "where"
1608"with" "write" "xor"
1609))
1610
1611	(mysql-types (sql-keywords-re
1612"bigint" "binary" "bit" "blob" "bool" "boolean" "char" "curve" "date"
1613"datetime" "dec" "decimal" "double" "enum" "fixed" "float" "geometry"
1614"geometrycollection" "int" "integer" "line" "linearring" "linestring"
1615"longblob" "longtext" "mediumblob" "mediumint" "mediumtext"
1616"multicurve" "multilinestring" "multipoint" "multipolygon"
1617"multisurface" "national" "numeric" "point" "polygon" "precision"
1618"real" "smallint" "surface" "text" "time" "timestamp" "tinyblob"
1619"tinyint" "tinytext" "unsigned" "varchar" "year" "year2" "year4"
1620"zerofill"
1621)))
1622
1623    `((,mysql-funcs    . font-lock-builtin-face)
1624      (,mysql-keywords . font-lock-keyword-face)
1625      (,mysql-types    . font-lock-type-face)))
1626
1627  "MySQL SQL keywords used by font-lock.
1628
1629This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1630regular expressions are created during compilation by calling the
1631function `regexp-opt'.  Therefore, take a look at the source before
1632you define your own sql-mode-mysql-font-lock-keywords.")
1633
1634(defvar sql-mode-sqlite-font-lock-keywords nil
1635  "SQLite SQL keywords used by font-lock.
1636
1637This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1638regular expressions are created during compilation by calling the
1639function `regexp-opt'.  Therefore, take a look at the source before
1640you define your own sql-mode-sqlite-font-lock-keywords.")
1641
1642(defvar sql-mode-db2-font-lock-keywords nil
1643  "DB2 SQL keywords used by font-lock.
1644
1645This variable is used by `sql-mode' and `sql-interactive-mode'.  The
1646regular expressions are created during compilation by calling the
1647function `regexp-opt'.  Therefore, take a look at the source before
1648you define your own sql-mode-db2-font-lock-keywords.")
1649
1650(defvar sql-mode-font-lock-keywords nil
1651  "SQL keywords used by font-lock.
1652
1653Setting this variable directly no longer has any affect.  Use
1654`sql-product' and `sql-add-product-keywords' to control the
1655highlighting rules in sql-mode.")
1656
1657
1658
1659;;; SQL Product support functions
1660
1661(defun sql-product-feature (feature &optional product)
1662  "Lookup `feature' needed to support the current SQL product.
1663
1664See \[sql-product-alist] for a list of products and supported features."
1665  (plist-get
1666   (cdr (assoc (or product sql-product)
1667	       sql-product-alist))
1668   feature))
1669
1670(defun sql-product-font-lock (keywords-only imenu)
1671  "Sets `font-lock-defaults' and `font-lock-keywords' based on
1672the product-specific keywords and syntax-alists defined in
1673`sql-product-alist'."
1674  (let
1675      ;; Get the product-specific syntax-alist.
1676      ((syntax-alist
1677	(append
1678	 (sql-product-feature :syntax-alist)
1679	 '((?_ . "w") (?. . "w")))))
1680
1681    ;; Get the product-specific keywords.
1682    (setq sql-mode-font-lock-keywords
1683	  (append
1684	   (unless (eq sql-product 'ansi)
1685	     (eval (sql-product-feature :font-lock)))
1686	   ;; Always highlight ANSI keywords
1687	   (eval (sql-product-feature :font-lock 'ansi))
1688	   ;; Fontify object names in CREATE, DROP and ALTER DDL
1689	   ;; statements
1690	   (list sql-mode-font-lock-object-name)))
1691
1692    ;; Setup font-lock.  Force re-parsing of `font-lock-defaults'.
1693    (set (make-local-variable 'font-lock-set-defaults) nil)
1694    (setq font-lock-defaults (list 'sql-mode-font-lock-keywords
1695				   keywords-only t syntax-alist))
1696
1697    ;; Force font lock to reinitialize if it is already on
1698    ;; Otherwise, we can wait until it can be started.
1699    (when (and (fboundp 'font-lock-mode)
1700	       font-lock-mode)
1701      (font-lock-mode-internal nil)
1702      (font-lock-mode-internal t))
1703
1704    (add-hook 'font-lock-mode-hook
1705	      (lambda ()
1706		;; Provide defaults for new font-lock faces.
1707		(defvar font-lock-builtin-face
1708		  (if (boundp 'font-lock-preprocessor-face)
1709		      font-lock-preprocessor-face
1710		    font-lock-keyword-face))
1711		(defvar font-lock-doc-face font-lock-string-face))
1712	      nil t)
1713
1714    ;; Setup imenu; it needs the same syntax-alist.
1715    (when imenu
1716	(setq imenu-syntax-alist syntax-alist))))
1717
1718;;;###autoload
1719(defun sql-add-product-keywords (product keywords &optional append)
1720  "Add highlighting KEYWORDS for SQL PRODUCT.
1721
1722PRODUCT should be a symbol, the name of a sql product, such as
1723`oracle'.  KEYWORDS should be a list; see the variable
1724`font-lock-keywords'.  By default they are added at the beginning
1725of the current highlighting list.  If optional argument APPEND is
1726`set', they are used to replace the current highlighting list.
1727If APPEND is any other non-nil value, they are added at the end
1728of the current highlighting list.
1729
1730For example:
1731
1732 (sql-add-product-keywords 'ms
1733  '((\"\\\\b\\\\w+_t\\\\b\" . font-lock-type-face)))
1734
1735adds a fontification pattern to fontify identifiers ending in
1736`_t' as data types."
1737
1738  (let ((font-lock (sql-product-feature :font-lock product))
1739	old)
1740    (setq old (eval font-lock))
1741    (set font-lock
1742	 (if (eq append 'set)
1743	     keywords
1744	   (if append
1745	       (append old keywords)
1746	     (append keywords old))))))
1747
1748
1749
1750;;; Functions to switch highlighting
1751
1752(defun sql-highlight-product ()
1753  "Turns on the appropriate font highlighting for the SQL product
1754selected."
1755
1756  (when (eq major-mode 'sql-mode)
1757    ;; Setup font-lock
1758    (sql-product-font-lock nil t)
1759
1760    ;; Set the mode name to include the product.
1761    (setq mode-name (concat "SQL[" (prin1-to-string sql-product) "]"))))
1762
1763(defun sql-set-product (product)
1764  "Set `sql-product' to product and enable appropriate
1765highlighting."
1766  (interactive "SEnter SQL product: ")
1767  (when (not (assoc product sql-product-alist))
1768    (error "SQL product %s is not supported; treated as ANSI" product)
1769    (setq product 'ansi))
1770
1771  ;; Save product setting and fontify.
1772  (setq sql-product product)
1773  (sql-highlight-product))
1774
1775(defun sql-highlight-oracle-keywords ()
1776  "Highlight Oracle keywords."
1777  (interactive)
1778  (sql-set-product 'oracle))
1779
1780(defun sql-highlight-postgres-keywords ()
1781  "Highlight Postgres keywords."
1782  (interactive)
1783  (sql-set-product 'postgres))
1784
1785(defun sql-highlight-linter-keywords ()
1786  "Highlight LINTER keywords."
1787  (interactive)
1788  (sql-set-product 'linter))
1789
1790(defun sql-highlight-ms-keywords ()
1791  "Highlight Microsoft SQLServer keywords."
1792  (interactive)
1793  (sql-set-product 'ms))
1794
1795(defun sql-highlight-ansi-keywords ()
1796  "Highlight ANSI SQL keywords."
1797  (interactive)
1798  (sql-set-product 'ansi))
1799
1800(defun sql-highlight-sybase-keywords ()
1801  "Highlight Sybase SQL keywords."
1802  (interactive)
1803  (sql-set-product 'sybase))
1804
1805(defun sql-highlight-informix-keywords ()
1806  "Highlight Informix SQL keywords."
1807  (interactive)
1808  (sql-set-product 'informix))
1809
1810(defun sql-highlight-interbase-keywords ()
1811  "Highlight Interbase SQL keywords."
1812  (interactive)
1813  (sql-set-product 'interbase))
1814
1815(defun sql-highlight-ingres-keywords ()
1816  "Highlight Ingres SQL keywords."
1817  (interactive)
1818  (sql-set-product 'ingres))
1819
1820(defun sql-highlight-solid-keywords ()
1821  "Highlight Solid SQL keywords."
1822  (interactive)
1823  (sql-set-product 'solid))
1824
1825(defun sql-highlight-mysql-keywords ()
1826  "Highlight MySQL SQL keywords."
1827  (interactive)
1828  (sql-set-product 'mysql))
1829
1830(defun sql-highlight-sqlite-keywords ()
1831  "Highlight SQLite SQL keywords."
1832  (interactive)
1833  (sql-set-product 'sqlite))
1834
1835(defun sql-highlight-db2-keywords ()
1836  "Highlight DB2 SQL keywords."
1837  (interactive)
1838  (sql-set-product 'db2))
1839
1840
1841
1842;;; Compatibility functions
1843
1844(if (not (fboundp 'comint-line-beginning-position))
1845    ;; comint-line-beginning-position is defined in Emacs 21
1846    (defun comint-line-beginning-position ()
1847      "Returns the buffer position of the beginning of the line, after any prompt.
1848The prompt is assumed to be any text at the beginning of the line matching
1849the regular expression `comint-prompt-regexp', a buffer local variable."
1850      (save-excursion (comint-bol nil) (point))))
1851
1852
1853
1854;;; Small functions
1855
1856(defun sql-magic-go (arg)
1857  "Insert \"o\" and call `comint-send-input'.
1858`sql-electric-stuff' must be the symbol `go'."
1859  (interactive "P")
1860  (self-insert-command (prefix-numeric-value arg))
1861  (if (and (equal sql-electric-stuff 'go)
1862	   (save-excursion
1863	     (comint-bol nil)
1864	     (looking-at "go\\b")))
1865      (comint-send-input)))
1866
1867(defun sql-magic-semicolon (arg)
1868  "Insert semicolon and call `comint-send-input'.
1869`sql-electric-stuff' must be the symbol `semicolon'."
1870  (interactive "P")
1871  (self-insert-command (prefix-numeric-value arg))
1872  (if (equal sql-electric-stuff 'semicolon)
1873       (comint-send-input)))
1874
1875(defun sql-accumulate-and-indent ()
1876  "Continue SQL statement on the next line."
1877  (interactive)
1878  (if (fboundp 'comint-accumulate)
1879      (comint-accumulate)
1880    (newline))
1881  (indent-according-to-mode))
1882
1883;;;###autoload
1884(defun sql-help ()
1885  "Show short help for the SQL modes.
1886
1887Use an entry function to open an interactive SQL buffer.  This buffer is
1888usually named `*SQL*'.  The name of the major mode is SQLi.
1889
1890Use the following commands to start a specific SQL interpreter:
1891
1892    PostGres: \\[sql-postgres]
1893    MySQL: \\[sql-mysql]
1894    SQLite: \\[sql-sqlite]
1895
1896Other non-free SQL implementations are also supported:
1897
1898    Solid: \\[sql-solid]
1899    Oracle: \\[sql-oracle]
1900    Informix: \\[sql-informix]
1901    Sybase: \\[sql-sybase]
1902    Ingres: \\[sql-ingres]
1903    Microsoft: \\[sql-ms]
1904    DB2: \\[sql-db2]
1905    Interbase: \\[sql-interbase]
1906    Linter: \\[sql-linter]
1907
1908But we urge you to choose a free implementation instead of these.
1909
1910Once you have the SQLi buffer, you can enter SQL statements in the
1911buffer.  The output generated is appended to the buffer and a new prompt
1912is generated.  See the In/Out menu in the SQLi buffer for some functions
1913that help you navigate through the buffer, the input history, etc.
1914
1915If you have a really complex SQL statement or if you are writing a
1916procedure, you can do this in a separate buffer.  Put the new buffer in
1917`sql-mode' by calling \\[sql-mode].  The name of this buffer can be
1918anything.  The name of the major mode is SQL.
1919
1920In this SQL buffer (SQL mode), you can send the region or the entire
1921buffer to the interactive SQL buffer (SQLi mode).  The results are
1922appended to the SQLi buffer without disturbing your SQL buffer."
1923  (interactive)
1924  (describe-function 'sql-help))
1925
1926(defun sql-read-passwd (prompt &optional default)
1927  "Read a password using PROMPT.  Optional DEFAULT is password to start with."
1928  (read-passwd prompt nil default))
1929
1930(defun sql-get-login (&rest what)
1931  "Get username, password and database from the user.
1932
1933The variables `sql-user', `sql-password', `sql-server', and
1934`sql-database' can be customized.  They are used as the default values.
1935Usernames, servers and databases are stored in `sql-user-history',
1936`sql-server-history' and `database-history'.  Passwords are not stored
1937in a history.
1938
1939Parameter WHAT is a list of the arguments passed to this function.
1940The function asks for the username if WHAT contains symbol `user', for
1941the password if it contains symbol `password', for the server if it
1942contains symbol `server', and for the database if it contains symbol
1943`database'.  The members of WHAT are processed in the order in which
1944they are provided.
1945
1946In order to ask the user for username, password and database, call the
1947function like this: (sql-get-login 'user 'password 'database)."
1948  (interactive)
1949  (while what
1950    (cond
1951     ((eq (car what) 'user)		; user
1952      (setq sql-user
1953	    (read-from-minibuffer "User: " sql-user nil nil
1954				  sql-user-history)))
1955     ((eq (car what) 'password)		; password
1956      (setq sql-password
1957	    (sql-read-passwd "Password: " sql-password)))
1958     ((eq (car what) 'server)		; server
1959      (setq sql-server
1960	    (read-from-minibuffer "Server: " sql-server nil nil
1961				  sql-server-history)))
1962     ((eq (car what) 'database)		; database
1963      (setq sql-database
1964	    (read-from-minibuffer "Database: " sql-database nil nil
1965				  sql-database-history))))
1966    (setq what (cdr what))))
1967
1968(defun sql-find-sqli-buffer ()
1969  "Return the current default SQLi buffer or nil.
1970In order to qualify, the SQLi buffer must be alive,
1971be in `sql-interactive-mode' and have a process."
1972  (let ((default-buffer (default-value 'sql-buffer)))
1973    (if (and (buffer-live-p default-buffer)
1974	     (get-buffer-process default-buffer))
1975	default-buffer
1976      (save-excursion
1977	(let ((buflist (buffer-list))
1978	      (found))
1979	  (while (not (or (null buflist)
1980			  found))
1981	    (let ((candidate (car buflist)))
1982	      (set-buffer candidate)
1983	      (if (and (equal major-mode 'sql-interactive-mode)
1984		       (get-buffer-process candidate))
1985		  (setq found candidate))
1986	      (setq buflist (cdr buflist))))
1987	  found)))))
1988
1989(defun sql-set-sqli-buffer-generally ()
1990  "Set SQLi buffer for all SQL buffers that have none.
1991This function checks all SQL buffers for their SQLi buffer.  If their
1992SQLi buffer is nonexistent or has no process, it is set to the current
1993default SQLi buffer.  The current default SQLi buffer is determined
1994using `sql-find-sqli-buffer'.  If `sql-buffer' is set,
1995`sql-set-sqli-hook' is run."
1996  (interactive)
1997  (save-excursion
1998    (let ((buflist (buffer-list))
1999	  (default-sqli-buffer (sql-find-sqli-buffer)))
2000      (setq-default sql-buffer default-sqli-buffer)
2001      (while (not (null buflist))
2002	(let ((candidate (car buflist)))
2003	  (set-buffer candidate)
2004	  (if (and (equal major-mode 'sql-mode)
2005		   (not (buffer-live-p sql-buffer)))
2006	      (progn
2007		(setq sql-buffer default-sqli-buffer)
2008		(run-hooks 'sql-set-sqli-hook))))
2009	(setq buflist (cdr buflist))))))
2010
2011(defun sql-set-sqli-buffer ()
2012  "Set the SQLi buffer SQL strings are sent to.
2013
2014Call this function in a SQL buffer in order to set the SQLi buffer SQL
2015strings are sent to.  Calling this function sets `sql-buffer' and runs
2016`sql-set-sqli-hook'.
2017
2018If you call it from a SQL buffer, this sets the local copy of
2019`sql-buffer'.
2020
2021If you call it from anywhere else, it sets the global copy of
2022`sql-buffer'."
2023  (interactive)
2024  (let ((default-buffer (sql-find-sqli-buffer)))
2025    (if (null default-buffer)
2026	(error "There is no suitable SQLi buffer"))
2027    (let ((new-buffer
2028	   (get-buffer
2029	    (read-buffer "New SQLi buffer: " default-buffer t))))
2030      (if (null (get-buffer-process new-buffer))
2031	  (error "Buffer %s has no process" (buffer-name new-buffer)))
2032      (if (null (save-excursion
2033		  (set-buffer new-buffer)
2034		  (equal major-mode 'sql-interactive-mode)))
2035	  (error "Buffer %s is no SQLi buffer" (buffer-name new-buffer)))
2036      (if new-buffer
2037	  (progn
2038	    (setq sql-buffer new-buffer)
2039	    (run-hooks 'sql-set-sqli-hook))))))
2040
2041(defun sql-show-sqli-buffer ()
2042  "Show the name of current SQLi buffer.
2043
2044This is the buffer SQL strings are sent to.  It is stored in the
2045variable `sql-buffer'.  See `sql-help' on how to create such a buffer."
2046  (interactive)
2047  (if (null (buffer-live-p sql-buffer))
2048      (message "%s has no SQLi buffer set." (buffer-name (current-buffer)))
2049    (if (null (get-buffer-process sql-buffer))
2050	(message "Buffer %s has no process." (buffer-name sql-buffer))
2051      (message "Current SQLi buffer is %s." (buffer-name sql-buffer)))))
2052
2053(defun sql-make-alternate-buffer-name ()
2054  "Return a string that can be used to rename a SQLi buffer.
2055
2056This is used to set `sql-alternate-buffer-name' within
2057`sql-interactive-mode'."
2058  (concat (if (string= "" sql-user)
2059	      (if (string= "" (user-login-name))
2060		  ()
2061		(concat (user-login-name) "/"))
2062	    (concat sql-user "/"))
2063	  (if (string= "" sql-database)
2064	      (if (string= "" sql-server)
2065		  (system-name)
2066		sql-server)
2067	    sql-database)))
2068
2069(defun sql-rename-buffer ()
2070  "Renames a SQLi buffer."
2071  (interactive)
2072  (rename-buffer (format "*SQL: %s*" sql-alternate-buffer-name) t))
2073
2074(defun sql-copy-column ()
2075  "Copy current column to the end of buffer.
2076Inserts SELECT or commas if appropriate."
2077  (interactive)
2078  (let ((column))
2079    (save-excursion
2080      (setq column (buffer-substring
2081		  (progn (forward-char 1) (backward-sexp 1) (point))
2082		  (progn (forward-sexp 1) (point))))
2083      (goto-char (point-max))
2084      (let ((bol (comint-line-beginning-position)))
2085	(cond
2086	 ;; if empty command line, insert SELECT
2087	 ((= bol (point))
2088	  (insert "SELECT "))
2089	 ;; else if appending to INTO .* (, SELECT or ORDER BY, insert a comma
2090	 ((save-excursion
2091	    (re-search-backward "\\b\\(\\(into\\s-+\\S-+\\s-+(\\)\\|select\\|order by\\) .+"
2092				bol t))
2093	  (insert ", "))
2094	 ;; else insert a space
2095	 (t
2096	  (if (eq (preceding-char) ?\s)
2097	      nil
2098	    (insert " ")))))
2099      ;; in any case, insert the column
2100      (insert column)
2101      (message "%s" column))))
2102
2103;; On NT, SQL*Plus for Oracle turns on full buffering for stdout if it
2104;; is not attached to a character device; therefore placeholder
2105;; replacement by SQL*Plus is fully buffered.  The workaround lets
2106;; Emacs query for the placeholders.
2107
2108(defvar sql-placeholder-history nil
2109  "History of placeholder values used.")
2110
2111(defun sql-query-placeholders-and-send (proc string)
2112  "Send to PROC input STRING, maybe replacing placeholders.
2113Placeholders are words starting with and ampersand like &this.
2114This function is used for `comint-input-sender' if using `sql-oracle' on NT."
2115  (while (string-match "&\\(\\sw+\\)" string)
2116    (setq string (replace-match
2117		  (read-from-minibuffer
2118		   (format "Enter value for %s: " (match-string 1 string))
2119		   nil nil nil sql-placeholder-history)
2120		  t t string)))
2121  (comint-send-string proc string)
2122  (if comint-input-sender-no-newline
2123      (if (not (string-equal string ""))
2124	  (process-send-eof))
2125    (comint-send-string proc "\n")))
2126
2127;; Using DB2 interactively, newlines must be escaped with " \".
2128;; The space before the backslash is relevant.
2129(defun sql-escape-newlines-and-send (proc string)
2130  "Send to PROC input STRING, escaping newlines if necessary.
2131Every newline in STRING will be preceded with a space and a backslash."
2132  (let ((result "") (start 0) mb me)
2133    (while (string-match "\n" string start)
2134      (setq mb (match-beginning 0)
2135	    me (match-end 0))
2136      (if (and (> mb 1)
2137	       (string-equal " \\" (substring string (- mb 2) mb)))
2138	  (setq result (concat result (substring string start me)))
2139	(setq result (concat result (substring string start mb) " \\\n")))
2140      (setq start me))
2141    (setq result (concat result (substring string start)))
2142    (comint-send-string proc result)
2143    (if comint-input-sender-no-newline
2144	(if (not (string-equal string ""))
2145	    (process-send-eof))
2146      (comint-send-string proc "\n"))))
2147
2148
2149
2150;;; Sending the region to the SQLi buffer.
2151
2152(defun sql-send-region (start end)
2153  "Send a region to the SQL process."
2154  (interactive "r")
2155  (if (buffer-live-p sql-buffer)
2156      (save-excursion
2157	(comint-send-region sql-buffer start end)
2158	(if (string-match "\n$" (buffer-substring start end))
2159	    ()
2160	  (comint-send-string sql-buffer "\n"))
2161	(message "Sent string to buffer %s." (buffer-name sql-buffer))
2162	(if sql-pop-to-buffer-after-send-region
2163	    (pop-to-buffer sql-buffer)
2164	  (display-buffer sql-buffer)))
2165    (message "No SQL process started.")))
2166
2167(defun sql-send-paragraph ()
2168  "Send the current paragraph to the SQL process."
2169  (interactive)
2170  (let ((start (save-excursion
2171		 (backward-paragraph)
2172		 (point)))
2173	(end (save-excursion
2174	       (forward-paragraph)
2175	       (point))))
2176    (sql-send-region start end)))
2177
2178(defun sql-send-buffer ()
2179  "Send the buffer contents to the SQL process."
2180  (interactive)
2181  (sql-send-region (point-min) (point-max)))
2182
2183(defun sql-send-string (str)
2184  "Send a string to the SQL process."
2185  (interactive "sSQL Text: ")
2186  (if (buffer-live-p sql-buffer)
2187      (save-excursion
2188        (comint-send-string sql-buffer str)
2189        (comint-send-string sql-buffer "\n")
2190        (message "Sent string to buffer %s." (buffer-name sql-buffer))
2191        (if sql-pop-to-buffer-after-send-region
2192            (pop-to-buffer sql-buffer)
2193          (display-buffer sql-buffer)))
2194    (message "No SQL process started.")))
2195
2196(defun sql-toggle-pop-to-buffer-after-send-region (&optional value)
2197  "Toggle `sql-pop-to-buffer-after-send-region'.
2198
2199If given the optional parameter VALUE, sets
2200sql-toggle-pop-to-buffer-after-send-region to VALUE."
2201  (interactive "P")
2202  (if value
2203      (setq sql-pop-to-buffer-after-send-region value)
2204    (setq sql-pop-to-buffer-after-send-region
2205	  (null sql-pop-to-buffer-after-send-region ))))
2206
2207
2208
2209;;; SQL mode -- uses SQL interactive mode
2210
2211;;;###autoload
2212(defun sql-mode ()
2213  "Major mode to edit SQL.
2214
2215You can send SQL statements to the SQLi buffer using
2216\\[sql-send-region].  Such a buffer must exist before you can do this.
2217See `sql-help' on how to create SQLi buffers.
2218
2219\\{sql-mode-map}
2220Customization: Entry to this mode runs the `sql-mode-hook'.
2221
2222When you put a buffer in SQL mode, the buffer stores the last SQLi
2223buffer created as its destination in the variable `sql-buffer'.  This
2224will be the buffer \\[sql-send-region] sends the region to.  If this
2225SQLi buffer is killed, \\[sql-send-region] is no longer able to
2226determine where the strings should be sent to.  You can set the
2227value of `sql-buffer' using \\[sql-set-sqli-buffer].
2228
2229For information on how to create multiple SQLi buffers, see
2230`sql-interactive-mode'.
2231
2232Note that SQL doesn't have an escape character unless you specify
2233one.  If you specify backslash as escape character in SQL,
2234you must tell Emacs.  Here's how to do that in your `~/.emacs' file:
2235
2236\(add-hook 'sql-mode-hook
2237          (lambda ()
2238	    (modify-syntax-entry ?\\\\ \".\" sql-mode-syntax-table)))"
2239  (interactive)
2240  (kill-all-local-variables)
2241  (setq major-mode 'sql-mode)
2242  (setq mode-name "SQL")
2243  (use-local-map sql-mode-map)
2244  (if sql-mode-menu
2245      (easy-menu-add sql-mode-menu)); XEmacs
2246  (set-syntax-table sql-mode-syntax-table)
2247  (make-local-variable 'font-lock-defaults)
2248  (make-local-variable 'sql-mode-font-lock-keywords)
2249  (make-local-variable 'comment-start)
2250  (setq comment-start "--")
2251  ;; Make each buffer in sql-mode remember the "current" SQLi buffer.
2252  (make-local-variable 'sql-buffer)
2253  ;; Add imenu support for sql-mode.  Note that imenu-generic-expression
2254  ;; is buffer-local, so we don't need a local-variable for it.  SQL is
2255  ;; case-insensitive, that's why we have to set imenu-case-fold-search.
2256  (setq imenu-generic-expression sql-imenu-generic-expression
2257	imenu-case-fold-search t)
2258  ;; Make `sql-send-paragraph' work on paragraphs that contain indented
2259  ;; lines.
2260  (make-local-variable 'paragraph-separate)
2261  (make-local-variable 'paragraph-start)
2262  (setq paragraph-separate "[\f]*$"
2263	paragraph-start "[\n\f]")
2264  ;; Abbrevs
2265  (setq local-abbrev-table sql-mode-abbrev-table)
2266  (setq abbrev-all-caps 1)
2267  ;; Run hook
2268  (run-mode-hooks 'sql-mode-hook)
2269  ;; Catch changes to sql-product and highlight accordingly
2270  (sql-highlight-product)
2271  (add-hook 'hack-local-variables-hook 'sql-highlight-product t t))
2272
2273
2274
2275;;; SQL interactive mode
2276
2277(put 'sql-interactive-mode 'mode-class 'special)
2278
2279(defun sql-interactive-mode ()
2280  "Major mode to use a SQL interpreter interactively.
2281
2282Do not call this function by yourself.  The environment must be
2283initialized by an entry function specific for the SQL interpreter.  See
2284`sql-help' for a list of available entry functions.
2285
2286\\[comint-send-input] after the end of the process' output sends the
2287text from the end of process to the end of the current line.
2288\\[comint-send-input] before end of process output copies the current
2289line minus the prompt to the end of the buffer and sends it.
2290\\[comint-copy-old-input] just copies the current line.
2291Use \\[sql-accumulate-and-indent] to enter multi-line statements.
2292
2293If you want to make multiple SQL buffers, rename the `*SQL*' buffer
2294using \\[rename-buffer] or \\[rename-uniquely] and start a new process.
2295See `sql-help' for a list of available entry functions.  The last buffer
2296created by such an entry function is the current SQLi buffer.  SQL
2297buffers will send strings to the SQLi buffer current at the time of
2298their creation.  See `sql-mode' for details.
2299
2300Sample session using two connections:
2301
23021. Create first SQLi buffer by calling an entry function.
23032. Rename buffer \"*SQL*\" to \"*Connection 1*\".
23043. Create a SQL buffer \"test1.sql\".
23054. Create second SQLi buffer by calling an entry function.
23065. Rename buffer \"*SQL*\" to \"*Connection 2*\".
23076. Create a SQL buffer \"test2.sql\".
2308
2309Now \\[sql-send-region] in buffer \"test1.sql\" will send the region to
2310buffer \"*Connection 1*\", \\[sql-send-region] in buffer \"test2.sql\"
2311will send the region to buffer \"*Connection 2*\".
2312
2313If you accidentally suspend your process, use \\[comint-continue-subjob]
2314to continue it.  On some operating systems, this will not work because
2315the signals are not supported.
2316
2317\\{sql-interactive-mode-map}
2318Customization: Entry to this mode runs the hooks on `comint-mode-hook'
2319and `sql-interactive-mode-hook' (in that order).  Before each input, the
2320hooks on `comint-input-filter-functions' are run.  After each SQL
2321interpreter output, the hooks on `comint-output-filter-functions' are
2322run.
2323
2324Variable `sql-input-ring-file-name' controls the initialization of the
2325input ring history.
2326
2327Variables `comint-output-filter-functions', a hook, and
2328`comint-scroll-to-bottom-on-input' and
2329`comint-scroll-to-bottom-on-output' control whether input and output
2330cause the window to scroll to the end of the buffer.
2331
2332If you want to make SQL buffers limited in length, add the function
2333`comint-truncate-buffer' to `comint-output-filter-functions'.
2334
2335Here is an example for your .emacs file.  It keeps the SQLi buffer a
2336certain length.
2337
2338\(add-hook 'sql-interactive-mode-hook
2339    \(function (lambda ()
2340        \(setq comint-output-filter-functions 'comint-truncate-buffer))))
2341
2342Here is another example.  It will always put point back to the statement
2343you entered, right above the output it created.
2344
2345\(setq comint-output-filter-functions
2346       \(function (lambda (STR) (comint-show-output))))"
2347  (delay-mode-hooks (comint-mode))
2348  ;; Get the `sql-product' for this interactive session.
2349  (set (make-local-variable 'sql-product)
2350       (or sql-interactive-product
2351	   sql-product))
2352  ;; Setup the mode.
2353  (setq major-mode 'sql-interactive-mode)
2354  (setq mode-name (concat "SQLi[" (prin1-to-string sql-product) "]"))
2355  (use-local-map sql-interactive-mode-map)
2356  (if sql-interactive-mode-menu
2357      (easy-menu-add sql-interactive-mode-menu)) ; XEmacs
2358  (set-syntax-table sql-mode-syntax-table)
2359  (make-local-variable 'sql-mode-font-lock-keywords)
2360  (make-local-variable 'font-lock-defaults)
2361  ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
2362  ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
2363  ;; will have just one quote.  Therefore syntactic hilighting is
2364  ;; disabled for interactive buffers.  No imenu support.
2365  (sql-product-font-lock t nil)
2366  ;; Enable commenting and uncommenting of the region.
2367  (make-local-variable 'comment-start)
2368  (setq comment-start "--")
2369  ;; Abbreviation table init and case-insensitive.  It is not activated
2370  ;; by default.
2371  (setq local-abbrev-table sql-mode-abbrev-table)
2372  (setq abbrev-all-caps 1)
2373  ;; Exiting the process will call sql-stop.
2374  (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop)
2375  ;; Create a usefull name for renaming this buffer later.
2376  (make-local-variable 'sql-alternate-buffer-name)
2377  (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name))
2378  ;; User stuff.  Initialize before the hook.
2379  (set (make-local-variable 'sql-prompt-regexp)
2380       (sql-product-feature :sqli-prompt-regexp))
2381  (set (make-local-variable 'sql-prompt-length)
2382       (sql-product-feature :sqli-prompt-length))
2383  (make-local-variable 'sql-input-ring-separator)
2384  (make-local-variable 'sql-input-ring-file-name)
2385  ;; Run hook.
2386  (run-mode-hooks 'sql-interactive-mode-hook)
2387  ;; Set comint based on user overrides.
2388  (setq comint-prompt-regexp sql-prompt-regexp)
2389  (setq left-margin sql-prompt-length)
2390  ;; People wanting a different history file for each
2391  ;; buffer/process/client/whatever can change separator and file-name
2392  ;; on the sql-interactive-mode-hook.
2393  (setq comint-input-ring-separator sql-input-ring-separator
2394	comint-input-ring-file-name sql-input-ring-file-name)
2395  ;; Calling the hook before calling comint-read-input-ring allows users
2396  ;; to set comint-input-ring-file-name in sql-interactive-mode-hook.
2397  (comint-read-input-ring t))
2398
2399(defun sql-stop (process event)
2400  "Called when the SQL process is stopped.
2401
2402Writes the input history to a history file using
2403`comint-write-input-ring' and inserts a short message in the SQL buffer.
2404
2405This function is a sentinel watching the SQL interpreter process.
2406Sentinels will always get the two parameters PROCESS and EVENT."
2407  (comint-write-input-ring)
2408  (if (and (eq (current-buffer) sql-buffer)
2409	   (not buffer-read-only))
2410      (insert (format "\nProcess %s %s\n" process event))
2411    (message "Process %s %s" process event)))
2412
2413
2414
2415;;; Entry functions for different SQL interpreters.
2416
2417;;;###autoload
2418(defun sql-product-interactive (&optional product)
2419  "Run product interpreter as an inferior process.
2420
2421If buffer `*SQL*' exists but no process is running, make a new process.
2422If buffer exists and a process is running, just switch to buffer
2423`*SQL*'.
2424
2425\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2426  (interactive)
2427  (setq product (or product sql-product))
2428  (when (sql-product-feature :sqli-connect product)
2429    (if (comint-check-proc "*SQL*")
2430	(pop-to-buffer "*SQL*")
2431      ;; Get credentials.
2432      (apply 'sql-get-login (sql-product-feature :sqli-login product))
2433      ;; Connect to database.
2434      (message "Login...")
2435      (funcall (sql-product-feature :sqli-connect product))
2436      ;; Set SQLi mode.
2437      (setq sql-interactive-product product)
2438      (setq sql-buffer (current-buffer))
2439      (sql-interactive-mode)
2440      ;; All done.
2441      (message "Login...done")
2442      (pop-to-buffer sql-buffer))))
2443
2444;;;###autoload
2445(defun sql-oracle ()
2446  "Run sqlplus by Oracle as an inferior process.
2447
2448If buffer `*SQL*' exists but no process is running, make a new process.
2449If buffer exists and a process is running, just switch to buffer
2450`*SQL*'.
2451
2452Interpreter used comes from variable `sql-oracle-program'.  Login uses
2453the variables `sql-user', `sql-password', and `sql-database' as
2454defaults, if set.  Additional command line parameters can be stored in
2455the list `sql-oracle-options'.
2456
2457The buffer is put in sql-interactive-mode, giving commands for sending
2458input.  See `sql-interactive-mode'.
2459
2460To specify a coding system for converting non-ASCII characters
2461in the input and output to the process, use \\[universal-coding-system-argument]
2462before \\[sql-oracle].  You can also specify this with \\[set-buffer-process-coding-system]
2463in the SQL buffer, after you start the process.
2464The default comes from `process-coding-system-alist' and
2465`default-process-coding-system'.
2466
2467\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2468  (interactive)
2469  (sql-product-interactive 'oracle))
2470
2471(defun sql-connect-oracle ()
2472  "Create comint buffer and connect to Oracle using the login
2473parameters and command options."
2474  ;; Produce user/password@database construct.  Password without user
2475  ;; is meaningless; database without user/password is meaningless,
2476  ;; because "@param" will ask sqlplus to interpret the script
2477  ;; "param".
2478  (let ((parameter nil))
2479    (if (not (string= "" sql-user))
2480	(if (not (string= "" sql-password))
2481	    (setq parameter (concat sql-user "/" sql-password))
2482	  (setq parameter sql-user)))
2483    (if (and parameter (not (string= "" sql-database)))
2484	(setq parameter (concat parameter "@" sql-database)))
2485    (if parameter
2486	(setq parameter (nconc (list parameter) sql-oracle-options))
2487      (setq parameter sql-oracle-options))
2488    (if parameter
2489	(set-buffer (apply 'make-comint "SQL" sql-oracle-program nil
2490			   parameter))
2491      (set-buffer (make-comint "SQL" sql-oracle-program nil)))
2492    ;; SQL*Plus is buffered on WindowsNT; this handles &placeholders.
2493    (if (eq window-system 'w32)
2494	(setq comint-input-sender 'sql-query-placeholders-and-send))))
2495
2496
2497
2498;;;###autoload
2499(defun sql-sybase ()
2500  "Run isql by SyBase as an inferior process.
2501
2502If buffer `*SQL*' exists but no process is running, make a new process.
2503If buffer exists and a process is running, just switch to buffer
2504`*SQL*'.
2505
2506Interpreter used comes from variable `sql-sybase-program'.  Login uses
2507the variables `sql-server', `sql-user', `sql-password', and
2508`sql-database' as defaults, if set.  Additional command line parameters
2509can be stored in the list `sql-sybase-options'.
2510
2511The buffer is put in sql-interactive-mode, giving commands for sending
2512input.  See `sql-interactive-mode'.
2513
2514To specify a coding system for converting non-ASCII characters
2515in the input and output to the process, use \\[universal-coding-system-argument]
2516before \\[sql-sybase].  You can also specify this with \\[set-buffer-process-coding-system]
2517in the SQL buffer, after you start the process.
2518The default comes from `process-coding-system-alist' and
2519`default-process-coding-system'.
2520
2521\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2522  (interactive)
2523  (sql-product-interactive 'sybase))
2524
2525(defun sql-connect-sybase ()
2526  "Create comint buffer and connect to Sybase using the login
2527parameters and command options."
2528  ;; Put all parameters to the program (if defined) in a list and call
2529  ;; make-comint.
2530  (let ((params sql-sybase-options))
2531    (if (not (string= "" sql-server))
2532	(setq params (append (list "-S" sql-server) params)))
2533    (if (not (string= "" sql-database))
2534	(setq params (append (list "-D" sql-database) params)))
2535    (if (not (string= "" sql-password))
2536	(setq params (append (list "-P" sql-password) params)))
2537    (if (not (string= "" sql-user))
2538	(setq params (append (list "-U" sql-user) params)))
2539    (set-buffer (apply 'make-comint "SQL" sql-sybase-program
2540		       nil params))))
2541
2542
2543
2544;;;###autoload
2545(defun sql-informix ()
2546  "Run dbaccess by Informix as an inferior process.
2547
2548If buffer `*SQL*' exists but no process is running, make a new process.
2549If buffer exists and a process is running, just switch to buffer
2550`*SQL*'.
2551
2552Interpreter used comes from variable `sql-informix-program'.  Login uses
2553the variable `sql-database' as default, if set.
2554
2555The buffer is put in sql-interactive-mode, giving commands for sending
2556input.  See `sql-interactive-mode'.
2557
2558To specify a coding system for converting non-ASCII characters
2559in the input and output to the process, use \\[universal-coding-system-argument]
2560before \\[sql-informix].  You can also specify this with \\[set-buffer-process-coding-system]
2561in the SQL buffer, after you start the process.
2562The default comes from `process-coding-system-alist' and
2563`default-process-coding-system'.
2564
2565\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2566  (interactive)
2567  (sql-product-interactive 'informix))
2568
2569(defun sql-connect-informix ()
2570  "Create comint buffer and connect to Informix using the login
2571parameters and command options."
2572  ;; username and password are ignored.
2573  (if (string= "" sql-database)
2574      (set-buffer (make-comint "SQL" sql-informix-program nil))
2575    (set-buffer (make-comint "SQL" sql-informix-program nil sql-database "-"))))
2576
2577
2578
2579;;;###autoload
2580(defun sql-sqlite ()
2581  "Run sqlite as an inferior process.
2582
2583SQLite is free software.
2584
2585If buffer `*SQL*' exists but no process is running, make a new process.
2586If buffer exists and a process is running, just switch to buffer
2587`*SQL*'.
2588
2589Interpreter used comes from variable `sql-sqlite-program'.  Login uses
2590the variables `sql-user', `sql-password', `sql-database', and
2591`sql-server' as defaults, if set.  Additional command line parameters
2592can be stored in the list `sql-sqlite-options'.
2593
2594The buffer is put in sql-interactive-mode, giving commands for sending
2595input.  See `sql-interactive-mode'.
2596
2597To specify a coding system for converting non-ASCII characters
2598in the input and output to the process, use \\[universal-coding-system-argument]
2599before \\[sql-sqlite].  You can also specify this with \\[set-buffer-process-coding-system]
2600in the SQL buffer, after you start the process.
2601The default comes from `process-coding-system-alist' and
2602`default-process-coding-system'.
2603
2604\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2605  (interactive)
2606  (sql-product-interactive 'sqlite))
2607
2608(defun sql-connect-sqlite ()
2609  "Create comint buffer and connect to SQLite using the login
2610parameters and command options."
2611  ;; Put all parameters to the program (if defined) in a list and call
2612  ;; make-comint.
2613  (let ((params))
2614    (if (not (string= "" sql-database))
2615	(setq params (append (list sql-database) params)))
2616    (if (not (string= "" sql-server))
2617	(setq params (append (list (concat "--host=" sql-server)) params)))
2618    (if (not (string= "" sql-password))
2619	(setq params (append (list (concat "--password=" sql-password)) params)))
2620    (if (not (string= "" sql-user))
2621	(setq params (append (list (concat "--user=" sql-user)) params)))
2622    (if (not (null sql-sqlite-options))
2623	(setq params (append sql-sqlite-options params)))
2624    (set-buffer (apply 'make-comint "SQL" sql-sqlite-program
2625		       nil params))))
2626
2627
2628
2629;;;###autoload
2630(defun sql-mysql ()
2631  "Run mysql by TcX as an inferior process.
2632
2633Mysql versions 3.23 and up are free software.
2634
2635If buffer `*SQL*' exists but no process is running, make a new process.
2636If buffer exists and a process is running, just switch to buffer
2637`*SQL*'.
2638
2639Interpreter used comes from variable `sql-mysql-program'.  Login uses
2640the variables `sql-user', `sql-password', `sql-database', and
2641`sql-server' as defaults, if set.  Additional command line parameters
2642can be stored in the list `sql-mysql-options'.
2643
2644The buffer is put in sql-interactive-mode, giving commands for sending
2645input.  See `sql-interactive-mode'.
2646
2647To specify a coding system for converting non-ASCII characters
2648in the input and output to the process, use \\[universal-coding-system-argument]
2649before \\[sql-mysql].  You can also specify this with \\[set-buffer-process-coding-system]
2650in the SQL buffer, after you start the process.
2651The default comes from `process-coding-system-alist' and
2652`default-process-coding-system'.
2653
2654\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2655  (interactive)
2656  (sql-product-interactive 'mysql))
2657
2658(defun sql-connect-mysql ()
2659  "Create comint buffer and connect to MySQL using the login
2660parameters and command options."
2661  ;; Put all parameters to the program (if defined) in a list and call
2662  ;; make-comint.
2663  (let ((params))
2664    (if (not (string= "" sql-database))
2665	(setq params (append (list sql-database) params)))
2666    (if (not (string= "" sql-server))
2667	(setq params (append (list (concat "--host=" sql-server)) params)))
2668    (if (not (string= "" sql-password))
2669	(setq params (append (list (concat "--password=" sql-password)) params)))
2670    (if (not (string= "" sql-user))
2671	(setq params (append (list (concat "--user=" sql-user)) params)))
2672    (if (not (null sql-mysql-options))
2673	(setq params (append sql-mysql-options params)))
2674    (set-buffer (apply 'make-comint "SQL" sql-mysql-program
2675		       nil params))))
2676
2677
2678
2679;;;###autoload
2680(defun sql-solid ()
2681  "Run solsql by Solid as an inferior process.
2682
2683If buffer `*SQL*' exists but no process is running, make a new process.
2684If buffer exists and a process is running, just switch to buffer
2685`*SQL*'.
2686
2687Interpreter used comes from variable `sql-solid-program'.  Login uses
2688the variables `sql-user', `sql-password', and `sql-server' as
2689defaults, if set.
2690
2691The buffer is put in sql-interactive-mode, giving commands for sending
2692input.  See `sql-interactive-mode'.
2693
2694To specify a coding system for converting non-ASCII characters
2695in the input and output to the process, use \\[universal-coding-system-argument]
2696before \\[sql-solid].  You can also specify this with \\[set-buffer-process-coding-system]
2697in the SQL buffer, after you start the process.
2698The default comes from `process-coding-system-alist' and
2699`default-process-coding-system'.
2700
2701\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2702  (interactive)
2703  (sql-product-interactive 'solid))
2704
2705(defun sql-connect-solid ()
2706  "Create comint buffer and connect to Solid using the login
2707parameters and command options."
2708  ;; Put all parameters to the program (if defined) in a list and call
2709  ;; make-comint.
2710  (let ((params))
2711    ;; It only makes sense if both username and password are there.
2712    (if (not (or (string= "" sql-user)
2713		 (string= "" sql-password)))
2714	(setq params (append (list sql-user sql-password) params)))
2715    (if (not (string= "" sql-server))
2716	(setq params (append (list sql-server) params)))
2717    (set-buffer (apply 'make-comint "SQL" sql-solid-program
2718		       nil params))))
2719
2720
2721
2722;;;###autoload
2723(defun sql-ingres ()
2724  "Run sql by Ingres as an inferior process.
2725
2726If buffer `*SQL*' exists but no process is running, make a new process.
2727If buffer exists and a process is running, just switch to buffer
2728`*SQL*'.
2729
2730Interpreter used comes from variable `sql-ingres-program'.  Login uses
2731the variable `sql-database' as default, if set.
2732
2733The buffer is put in sql-interactive-mode, giving commands for sending
2734input.  See `sql-interactive-mode'.
2735
2736To specify a coding system for converting non-ASCII characters
2737in the input and output to the process, use \\[universal-coding-system-argument]
2738before \\[sql-ingres].  You can also specify this with \\[set-buffer-process-coding-system]
2739in the SQL buffer, after you start the process.
2740The default comes from `process-coding-system-alist' and
2741`default-process-coding-system'.
2742
2743\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2744  (interactive)
2745  (sql-product-interactive 'ingres))
2746
2747(defun sql-connect-ingres ()
2748  "Create comint buffer and connect to Ingres using the login
2749parameters and command options."
2750  ;; username and password are ignored.
2751  (if (string= "" sql-database)
2752      (set-buffer (make-comint "SQL" sql-ingres-program nil))
2753    (set-buffer (make-comint "SQL" sql-ingres-program nil sql-database))))
2754
2755
2756
2757;;;###autoload
2758(defun sql-ms ()
2759  "Run osql by Microsoft as an inferior process.
2760
2761If buffer `*SQL*' exists but no process is running, make a new process.
2762If buffer exists and a process is running, just switch to buffer
2763`*SQL*'.
2764
2765Interpreter used comes from variable `sql-ms-program'.  Login uses the
2766variables `sql-user', `sql-password', `sql-database', and `sql-server'
2767as defaults, if set.  Additional command line parameters can be stored
2768in the list `sql-ms-options'.
2769
2770The buffer is put in sql-interactive-mode, giving commands for sending
2771input.  See `sql-interactive-mode'.
2772
2773To specify a coding system for converting non-ASCII characters
2774in the input and output to the process, use \\[universal-coding-system-argument]
2775before \\[sql-ms].  You can also specify this with \\[set-buffer-process-coding-system]
2776in the SQL buffer, after you start the process.
2777The default comes from `process-coding-system-alist' and
2778`default-process-coding-system'.
2779
2780\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2781  (interactive)
2782  (sql-product-interactive 'ms))
2783
2784(defun sql-connect-ms ()
2785  "Create comint buffer and connect to Microsoft using the login
2786parameters and command options."
2787  ;; Put all parameters to the program (if defined) in a list and call
2788  ;; make-comint.
2789  (let ((params sql-ms-options))
2790    (if (not (string= "" sql-server))
2791        (setq params (append (list "-S" sql-server) params)))
2792    (if (not (string= "" sql-database))
2793        (setq params (append (list "-d" sql-database) params)))
2794    (if (not (string= "" sql-user))
2795	(setq params (append (list "-U" sql-user) params)))
2796    (if (not (string= "" sql-password))
2797	(setq params (append (list "-P" sql-password) params))
2798      (if (string= "" sql-user)
2799	  ;; if neither user nor password is provided, use system
2800	  ;; credentials.
2801	  (setq params (append (list "-E") params))
2802	;; If -P is passed to ISQL as the last argument without a
2803	;; password, it's considered null.
2804	(setq params (append params (list "-P")))))
2805    (set-buffer (apply 'make-comint "SQL" sql-ms-program
2806		       nil params))))
2807
2808
2809
2810;;;###autoload
2811(defun sql-postgres ()
2812  "Run psql by Postgres as an inferior process.
2813
2814If buffer `*SQL*' exists but no process is running, make a new process.
2815If buffer exists and a process is running, just switch to buffer
2816`*SQL*'.
2817
2818Interpreter used comes from variable `sql-postgres-program'.  Login uses
2819the variables `sql-database' and `sql-server' as default, if set.
2820Additional command line parameters can be stored in the list
2821`sql-postgres-options'.
2822
2823The buffer is put in sql-interactive-mode, giving commands for sending
2824input.  See `sql-interactive-mode'.
2825
2826To specify a coding system for converting non-ASCII characters
2827in the input and output to the process, use \\[universal-coding-system-argument]
2828before \\[sql-postgres].  You can also specify this with \\[set-buffer-process-coding-system]
2829in the SQL buffer, after you start the process.
2830The default comes from `process-coding-system-alist' and
2831`default-process-coding-system'.  If your output lines end with ^M,
2832your might try undecided-dos as a coding system.  If this doesn't help,
2833Try to set `comint-output-filter-functions' like this:
2834
2835\(setq comint-output-filter-functions (append comint-output-filter-functions
2836					     '(comint-strip-ctrl-m)))
2837
2838\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2839  (interactive)
2840  (sql-product-interactive 'postgres))
2841
2842(defun sql-connect-postgres ()
2843  "Create comint buffer and connect to Postgres using the login
2844parameters and command options."
2845  ;; username and password are ignored.  Mark Stosberg suggest to add
2846  ;; the database at the end.  Jason Beegan suggest using --pset and
2847  ;; pager=off instead of \\o|cat.  The later was the solution by
2848  ;; Gregor Zych.  Jason's suggestion is the default value for
2849  ;; sql-postgres-options.
2850  (let ((params sql-postgres-options))
2851    (if (not (string= "" sql-database))
2852	(setq params (append params (list sql-database))))
2853    (if (not (string= "" sql-server))
2854	(setq params (append (list "-h" sql-server) params)))
2855    (if (not (string= "" sql-user))
2856	(setq params (append (list "-U" sql-user) params)))
2857    (set-buffer (apply 'make-comint "SQL" sql-postgres-program
2858		       nil params))))
2859
2860
2861
2862;;;###autoload
2863(defun sql-interbase ()
2864  "Run isql by Interbase as an inferior process.
2865
2866If buffer `*SQL*' exists but no process is running, make a new process.
2867If buffer exists and a process is running, just switch to buffer
2868`*SQL*'.
2869
2870Interpreter used comes from variable `sql-interbase-program'.  Login
2871uses the variables `sql-user', `sql-password', and `sql-database' as
2872defaults, if set.
2873
2874The buffer is put in sql-interactive-mode, giving commands for sending
2875input.  See `sql-interactive-mode'.
2876
2877To specify a coding system for converting non-ASCII characters
2878in the input and output to the process, use \\[universal-coding-system-argument]
2879before \\[sql-interbase].  You can also specify this with \\[set-buffer-process-coding-system]
2880in the SQL buffer, after you start the process.
2881The default comes from `process-coding-system-alist' and
2882`default-process-coding-system'.
2883
2884\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2885  (interactive)
2886  (sql-product-interactive 'interbase))
2887
2888(defun sql-connect-interbase ()
2889  "Create comint buffer and connect to Interbase using the login
2890parameters and command options."
2891  ;; Put all parameters to the program (if defined) in a list and call
2892  ;; make-comint.
2893  (let ((params sql-interbase-options))
2894    (if (not (string= "" sql-user))
2895	(setq params (append (list "-u" sql-user) params)))
2896    (if (not (string= "" sql-password))
2897	(setq params (append (list "-p" sql-password) params)))
2898    (if (not (string= "" sql-database))
2899        (setq params (cons sql-database params))) ; add to the front!
2900    (set-buffer (apply 'make-comint "SQL" sql-interbase-program
2901		       nil params))))
2902
2903
2904
2905;;;###autoload
2906(defun sql-db2 ()
2907  "Run db2 by IBM as an inferior process.
2908
2909If buffer `*SQL*' exists but no process is running, make a new process.
2910If buffer exists and a process is running, just switch to buffer
2911`*SQL*'.
2912
2913Interpreter used comes from variable `sql-db2-program'.  There is not
2914automatic login.
2915
2916The buffer is put in sql-interactive-mode, giving commands for sending
2917input.  See `sql-interactive-mode'.
2918
2919If you use \\[sql-accumulate-and-indent] to send multiline commands to
2920db2, newlines will be escaped if necessary.  If you don't want that, set
2921`comint-input-sender' back to `comint-simple-send' by writing an after
2922advice.  See the elisp manual for more information.
2923
2924To specify a coding system for converting non-ASCII characters
2925in the input and output to the process, use \\[universal-coding-system-argument]
2926before \\[sql-db2].  You can also specify this with \\[set-buffer-process-coding-system]
2927in the SQL buffer, after you start the process.
2928The default comes from `process-coding-system-alist' and
2929`default-process-coding-system'.
2930
2931\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2932  (interactive)
2933  (sql-product-interactive 'db2))
2934
2935(defun sql-connect-db2 ()
2936  "Create comint buffer and connect to DB2 using the login
2937parameters and command options."
2938  ;; Put all parameters to the program (if defined) in a list and call
2939  ;; make-comint.
2940  (set-buffer (apply 'make-comint "SQL" sql-db2-program
2941		     nil sql-db2-options))
2942  ;; Properly escape newlines when DB2 is interactive.
2943  (setq comint-input-sender 'sql-escape-newlines-and-send))
2944
2945;;;###autoload
2946(defun sql-linter ()
2947  "Run inl by RELEX as an inferior process.
2948
2949If buffer `*SQL*' exists but no process is running, make a new process.
2950If buffer exists and a process is running, just switch to buffer
2951`*SQL*'.
2952
2953Interpreter used comes from variable `sql-linter-program' - usually `inl'.
2954Login uses the variables `sql-user', `sql-password', `sql-database' and
2955`sql-server' as defaults, if set.  Additional command line parameters
2956can be stored in the list `sql-linter-options'. Run inl -h to get help on
2957parameters.
2958
2959`sql-database' is used to set the LINTER_MBX environment variable for
2960local connections, `sql-server' refers to the server name from the
2961`nodetab' file for the network connection (dbc_tcp or friends must run
2962for this to work).  If `sql-password' is an empty string, inl will use
2963an empty password.
2964
2965The buffer is put in sql-interactive-mode, giving commands for sending
2966input.  See `sql-interactive-mode'.
2967
2968\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
2969  (interactive)
2970  (sql-product-interactive 'linter))
2971
2972(defun sql-connect-linter ()
2973  "Create comint buffer and connect to Linter using the login
2974parameters and command options."
2975  ;; Put all parameters to the program (if defined) in a list and call
2976  ;; make-comint.
2977  (let ((params sql-linter-options) (login nil) (old-mbx (getenv "LINTER_MBX")))
2978    (if (not (string= "" sql-user))
2979	(setq login (concat sql-user "/" sql-password)))
2980    (setq params (append (list "-u" login) params))
2981    (if (not (string= "" sql-server))
2982	(setq params (append (list "-n" sql-server) params)))
2983    (if (string= "" sql-database)
2984	(setenv "LINTER_MBX" nil)
2985      (setenv "LINTER_MBX" sql-database))
2986    (set-buffer (apply 'make-comint "SQL" sql-linter-program nil
2987		       params))
2988    (setenv "LINTER_MBX" old-mbx)))
2989
2990
2991
2992(provide 'sql)
2993
2994;;; arch-tag: 7e1fa1c4-9ca2-402e-87d2-83a5eccb7ac3
2995;;; sql.el ends here
2996