Convert several shell.el defvars to defcustoms.
[bpt/emacs.git] / lisp / progmodes / sql.el
CommitLineData
95e4b2ef
RS
1;;; sql.el --- specialized comint.el for SQL interpreters
2
bb5aa5d6 3;; Copyright (C) 1998-2012 Free Software Foundation, Inc.
95e4b2ef 4
1533eb58 5;; Author: Alex Schroeder <alex@gnu.org>
dc45d1a6 6;; Maintainer: Michael Mauger <mmaug@yahoo.com>
04e082b0 7;; Version: 3.1
dab100d7 8;; Keywords: comm languages processes
e084bc3d 9;; URL: http://savannah.gnu.org/projects/emacs/
95e4b2ef
RS
10
11;; This file is part of GNU Emacs.
12
b1fc2b50 13;; GNU Emacs is free software: you can redistribute it and/or modify
95e4b2ef 14;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
95e4b2ef
RS
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
b1fc2b50 24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
95e4b2ef
RS
25
26;;; Commentary:
27
c04bb32e 28;; Please send bug reports and bug fixes to the mailing list at
01295a22
RS
29;; help-gnu-emacs@gnu.org. If you want to subscribe to the mailing
30;; list, see the web page at
31;; http://lists.gnu.org/mailman/listinfo/help-gnu-emacs for
32;; instructions. I monitor this list actively. If you send an e-mail
33;; to Alex Schroeder it usually makes it to me when Alex has a chance
34;; to forward them along (Thanks, Alex).
35
36;; This file provides a sql-mode and a sql-interactive-mode. The
37;; original goals were two simple modes providing syntactic
38;; highlighting. The interactive mode had to provide a command-line
39;; history; the other mode had to provide "send region/buffer to SQL
40;; interpreter" functions. "simple" in this context means easy to
41;; use, easy to maintain and little or no bells and whistles. This
42;; has changed somewhat as experience with the mode has accumulated.
43
44;; Support for different flavors of SQL and command interpreters was
45;; available in early versions of sql.el. This support has been
46;; extended and formalized in later versions. Part of the impetus for
47;; the improved support of SQL flavors was borne out of the current
fbcc67e2 48;; maintainers consulting experience. In the past twenty years, I
01295a22
RS
49;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer.
50;; On some assignments, I have used two or more of these concurrently.
95e4b2ef
RS
51
52;; If anybody feels like extending this sql mode, take a look at the
53;; above mentioned modes and write a sqlx-mode on top of this one. If
54;; this proves to be difficult, please suggest changes that will
01295a22
RS
55;; facilitate your plans. Facilities have been provided to add
56;; products and product-specific configuration.
95e4b2ef
RS
57
58;; sql-interactive-mode is used to interact with a SQL interpreter
dab100d7 59;; process in a SQLi buffer (usually called `*SQL*'). The SQLi buffer
01295a22
RS
60;; is created by calling a SQL interpreter-specific entry function or
61;; sql-product-interactive. Do *not* call sql-interactive-mode by
62;; itself.
95e4b2ef
RS
63
64;; The list of currently supported interpreters and the corresponding
dab100d7 65;; entry function used to create the SQLi buffers is shown with
95e4b2ef
RS
66;; `sql-help' (M-x sql-help).
67
68;; Since sql-interactive-mode is built on top of the general
69;; command-interpreter-in-a-buffer mode (comint mode), it shares a
70;; common base functionality, and a common set of bindings, with all
71;; modes derived from comint mode. This makes these modes easier to
72;; use.
73
311e7a89
GM
74;; sql-mode can be used to keep editing SQL statements. The SQL
75;; statements can be sent to the SQL process in the SQLi buffer.
95e4b2ef
RS
76
77;; For documentation on the functionality provided by comint mode, and
eb3f61dd 78;; the hooks available for customizing it, see the file `comint.el'.
95e4b2ef 79
801d1cb0
AS
80;; Hint for newbies: take a look at `dabbrev-expand', `abbrev-mode', and
81;; `imenu-add-menubar-index'.
95e4b2ef
RS
82
83;;; Requirements for Emacs 19.34:
84
85;; If you are using Emacs 19.34, you will have to get and install
86;; the file regexp-opt.el
87;; <URL:ftp://ftp.ifi.uio.no/pub/emacs/emacs-20.3/lisp/emacs-lisp/regexp-opt.el>
88;; and the custom package
89;; <URL:http://www.dina.kvl.dk/~abraham/custom/>.
90
91;;; Bugs:
92
78024f88
AS
93;; sql-ms now uses osql instead of isql. Osql flushes its error
94;; stream more frequently than isql so that error messages are
95;; available. There is no prompt and some output still is buffered.
96;; This improves the interaction under Emacs but it still is somewhat
97;; awkward.
98
e4769531 99;; Quoted identifiers are not supported for highlighting. Most
78024f88
AS
100;; databases support the use of double quoted strings in place of
101;; identifiers; ms (Microsoft SQLServer) also supports identifiers
102;; enclosed within brackets [].
95e4b2ef 103
78024f88
AS
104;;; Product Support:
105
106;; To add support for additional SQL products the following steps
107;; must be followed ("xyz" is the name of the product in the examples
108;; below):
109
7492acc9 110;; 1) Add the product to the list of known products.
78024f88 111
7492acc9
MM
112;; (sql-add-product 'xyz "XyzDB"
113;; '(:free-software t))
78024f88 114
7492acc9
MM
115;; 2) Define font lock settings. All ANSI keywords will be
116;; highlighted automatically, so only product specific keywords
117;; need to be defined here.
78024f88 118
7492acc9
MM
119;; (defvar my-sql-mode-xyz-font-lock-keywords
120;; '(("\\b\\(red\\|orange\\|yellow\\)\\b"
121;; . font-lock-keyword-face))
122;; "XyzDB SQL keywords used by font-lock.")
78024f88 123
7492acc9
MM
124;; (sql-set-product-feature 'xyz
125;; :font-lock
126;; 'my-sql-mode-xyz-font-lock-keywords)
78024f88 127
7492acc9
MM
128;; 3) Define any special syntax characters including comments and
129;; identifier characters.
130
131;; (sql-set-product-feature 'xyz
fbcc67e2 132;; :syntax-alist ((?# . "_")))
7492acc9
MM
133
134;; 4) Define the interactive command interpreter for the database
135;; product.
136
137;; (defcustom my-sql-xyz-program "ixyz"
138;; "Command to start ixyz by XyzDB."
78024f88
AS
139;; :type 'file
140;; :group 'SQL)
141;;
7492acc9
MM
142;; (sql-set-product-feature 'xyz
143;; :sqli-program 'my-sql-xyz-program)
144;; (sql-set-product-feature 'xyz
145;; :prompt-regexp "^xyzdb> ")
146;; (sql-set-product-feature 'xyz
147;; :prompt-length 7)
148
149;; 5) Define login parameters and command line formatting.
150
151;; (defcustom my-sql-xyz-login-params '(user password server database)
152;; "Login parameters to needed to connect to XyzDB."
5474c40f 153;; :type 'sql-login-params
78024f88 154;; :group 'SQL)
7492acc9
MM
155;;
156;; (sql-set-product-feature 'xyz
157;; :sqli-login 'my-sql-xyz-login-params)
78024f88 158
7492acc9
MM
159;; (defcustom my-sql-xyz-options '("-X" "-Y" "-Z")
160;; "List of additional options for `sql-xyz-program'."
161;; :type '(repeat string)
162;; :group 'SQL)
163;;
164;; (sql-set-product-feature 'xyz
165;; :sqli-options 'my-sql-xyz-options))
78024f88 166
30c4d8dc 167;; (defun my-sql-comint-xyz (product options)
7492acc9 168;; "Connect ti XyzDB in a comint buffer."
78024f88
AS
169;;
170;; ;; Do something with `sql-user', `sql-password',
171;; ;; `sql-database', and `sql-server'.
7492acc9 172;; (let ((params options))
78024f88
AS
173;; (if (not (string= "" sql-server))
174;; (setq params (append (list "-S" sql-server) params)))
175;; (if (not (string= "" sql-database))
176;; (setq params (append (list "-D" sql-database) params)))
177;; (if (not (string= "" sql-password))
178;; (setq params (append (list "-P" sql-password) params)))
179;; (if (not (string= "" sql-user))
180;; (setq params (append (list "-U" sql-user) params)))
30c4d8dc 181;; (sql-comint product params)))
7492acc9
MM
182;;
183;; (sql-set-product-feature 'xyz
d26b0ea9 184;; :sqli-comint-func 'my-sql-comint-xyz)
78024f88 185
fbcc67e2 186;; 6) Define a convenience function to invoke the SQL interpreter.
7492acc9 187
9250002f 188;; (defun my-sql-xyz (&optional buffer)
7492acc9 189;; "Run ixyz by XyzDB as an inferior process."
9250002f
MM
190;; (interactive "P")
191;; (sql-product-interactive 'xyz buffer))
78024f88 192
b4dd5c9c
JB
193;;; To Do:
194
7492acc9
MM
195;; Improve keyword highlighting for individual products. I have tried
196;; to update those database that I use. Feel free to send me updates,
197;; or direct me to the reference manuals for your favorite database.
b4dd5c9c 198
7492acc9
MM
199;; When there are no keywords defined, the ANSI keywords are
200;; highlighted. ANSI keywords are highlighted even if the keyword is
201;; not used for your current product. This should help identify
202;; portability concerns.
203
204;; Add different highlighting levels.
205
206;; Add support for listing available tables or the columns in a table.
95e4b2ef
RS
207
208;;; Thanks to all the people who helped me out:
209
7492acc9 210;; Alex Schroeder <alex@gnu.org> -- the original author
95e4b2ef
RS
211;; Kai Blauberg <kai.blauberg@metla.fi>
212;; <ibalaban@dalet.com>
213;; Yair Friedman <yfriedma@JohnBryce.Co.Il>
214;; Gregor Zych <zych@pool.informatik.rwth-aachen.de>
a081a529 215;; nino <nino@inform.dk>
801d1cb0 216;; Berend de Boer <berend@pobox.com>
9fd8cb36 217;; Adam Jenkins <adam@thejenkins.org>
9a9069c9
SM
218;; Michael Mauger <mmaug@yahoo.com> -- improved product support
219;; Drew Adams <drew.adams@oracle.com> -- Emacs 20 support
220;; Harald Maier <maierh@myself.com> -- sql-send-string
04e082b0
MM
221;; Stefan Monnier <monnier@iro.umontreal.ca> -- font-lock corrections;
222;; code polish
bb5aa5d6
MM
223;; Paul Sleigh <bat@flurf.net> -- MySQL keyword enhancement
224;; Andrew Schein <andrew@andrewschein.com> -- sql-port bug
04e082b0
MM
225;; Ian Bjorhovde <idbjorh@dataproxy.com> -- db2 escape newlines
226;; incorrectly enabled by default
dab100d7 227
95e4b2ef
RS
228\f
229
230;;; Code:
231
232(require 'comint)
233;; Need the following to allow GNU Emacs 19 to compile the file.
78024f88
AS
234(eval-when-compile
235 (require 'regexp-opt))
95e4b2ef 236(require 'custom)
fbcc67e2 237(require 'thingatpt)
9fd8cb36 238(eval-when-compile ;; needed in Emacs 19, 20
d26b0ea9 239 (setq max-specpdl-size (max max-specpdl-size 2000)))
95e4b2ef 240
fbcc67e2
MM
241(defun sql-signum (n)
242 "Return 1, 0, or -1 to identify the sign of N."
243 (cond
244 ((not (numberp n)) nil)
245 ((< n 0) -1)
246 ((> n 0) 1)
247 (t 0)))
248
ec38bb46
JB
249(defvar font-lock-keyword-face)
250(defvar font-lock-set-defaults)
251(defvar font-lock-string-face)
252
95e4b2ef
RS
253;;; Allow customization
254
255(defgroup SQL nil
b9584f65 256 "Running a SQL interpreter from within Emacs buffers."
6629e5ba 257 :version "20.4"
7492acc9 258 :group 'languages
95e4b2ef
RS
259 :group 'processes)
260
78024f88 261;; These four variables will be used as defaults, if set.
95e4b2ef
RS
262
263(defcustom sql-user ""
7492acc9 264 "Default username."
95e4b2ef 265 :type 'string
30c4d8dc
MM
266 :group 'SQL
267 :safe 'stringp)
95e4b2ef
RS
268
269(defcustom sql-password ""
7492acc9 270 "Default password.
95e4b2ef
RS
271
272Storing your password in a textfile such as ~/.emacs could be dangerous.
273Customizing your password will store it in your ~/.emacs file."
274 :type 'string
30c4d8dc
MM
275 :group 'SQL
276 :risky t)
95e4b2ef
RS
277
278(defcustom sql-database ""
7492acc9 279 "Default database."
95e4b2ef 280 :type 'string
30c4d8dc
MM
281 :group 'SQL
282 :safe 'stringp)
95e4b2ef
RS
283
284(defcustom sql-server ""
7492acc9 285 "Default server or host."
95e4b2ef 286 :type 'string
30c4d8dc
MM
287 :group 'SQL
288 :safe 'stringp)
7492acc9 289
9250002f 290(defcustom sql-port 0
34e8a2da 291 "Default port for connecting to a MySQL or Postgres server."
30c4d8dc 292 :version "24.1"
7492acc9 293 :type 'number
30c4d8dc
MM
294 :group 'SQL
295 :safe 'numberp)
95e4b2ef 296
5474c40f
MM
297;; Login parameter type
298
299(define-widget 'sql-login-params 'lazy
300 "Widget definition of the login parameters list"
74790210
MM
301 ;; FIXME: does not implement :default property for the user,
302 ;; database and server options. Anybody have some guidance on how to
303 ;; do this.
5474c40f
MM
304 :tag "Login Parameters"
305 :type '(repeat (choice
306 (const user)
307 (const password)
308 (choice :tag "server"
309 (const server)
310 (list :tag "file"
311 (const :format "" server)
312 (const :format "" :file)
313 regexp)
314 (list :tag "completion"
315 (const :format "" server)
316 (const :format "" :completion)
317 (restricted-sexp
74790210 318 :match-alternatives (listp stringp))))
5474c40f
MM
319 (choice :tag "database"
320 (const database)
321 (list :tag "file"
322 (const :format "" database)
323 (const :format "" :file)
324 regexp)
325 (list :tag "completion"
326 (const :format "" database)
327 (const :format "" :completion)
328 (restricted-sexp
74790210 329 :match-alternatives (listp stringp))))
5474c40f
MM
330 (const port))))
331
78024f88 332;; SQL Product support
78024f88
AS
333
334(defvar sql-interactive-product nil
335 "Product under `sql-interactive-mode'.")
336
30c4d8dc
MM
337(defvar sql-connection nil
338 "Connection name if interactive session started by `sql-connect'.")
339
9fd8cb36 340(defvar sql-product-alist
78024f88 341 '((ansi
55659495 342 :name "ANSI"
fbcc67e2
MM
343 :font-lock sql-mode-ansi-font-lock-keywords
344 :statement sql-ansi-statement-starters)
7492acc9 345
78024f88 346 (db2
55659495 347 :name "DB2"
78024f88 348 :font-lock sql-mode-db2-font-lock-keywords
7492acc9
MM
349 :sqli-program sql-db2-program
350 :sqli-options sql-db2-options
351 :sqli-login sql-db2-login-params
30c4d8dc 352 :sqli-comint-func sql-comint-db2
7492acc9
MM
353 :prompt-regexp "^db2 => "
354 :prompt-length 7
3bd2cfef 355 :prompt-cont-regexp "^db2 (cont\.) => "
7492acc9
MM
356 :input-filter sql-escape-newlines-filter)
357
78024f88 358 (informix
7492acc9 359 :name "Informix"
78024f88 360 :font-lock sql-mode-informix-font-lock-keywords
7492acc9
MM
361 :sqli-program sql-informix-program
362 :sqli-options sql-informix-options
363 :sqli-login sql-informix-login-params
30c4d8dc 364 :sqli-comint-func sql-comint-informix
7492acc9
MM
365 :prompt-regexp "^> "
366 :prompt-length 2
367 :syntax-alist ((?{ . "<") (?} . ">")))
368
78024f88 369 (ingres
7492acc9 370 :name "Ingres"
78024f88 371 :font-lock sql-mode-ingres-font-lock-keywords
7492acc9
MM
372 :sqli-program sql-ingres-program
373 :sqli-options sql-ingres-options
374 :sqli-login sql-ingres-login-params
30c4d8dc 375 :sqli-comint-func sql-comint-ingres
7492acc9 376 :prompt-regexp "^\* "
3bd2cfef
MM
377 :prompt-length 2
378 :prompt-cont-regexp "^\* ")
7492acc9 379
78024f88 380 (interbase
7492acc9 381 :name "Interbase"
78024f88 382 :font-lock sql-mode-interbase-font-lock-keywords
7492acc9
MM
383 :sqli-program sql-interbase-program
384 :sqli-options sql-interbase-options
385 :sqli-login sql-interbase-login-params
30c4d8dc 386 :sqli-comint-func sql-comint-interbase
7492acc9
MM
387 :prompt-regexp "^SQL> "
388 :prompt-length 5)
389
78024f88 390 (linter
7492acc9 391 :name "Linter"
78024f88 392 :font-lock sql-mode-linter-font-lock-keywords
7492acc9
MM
393 :sqli-program sql-linter-program
394 :sqli-options sql-linter-options
395 :sqli-login sql-linter-login-params
30c4d8dc 396 :sqli-comint-func sql-comint-linter
7492acc9
MM
397 :prompt-regexp "^SQL>"
398 :prompt-length 4)
399
78024f88 400 (ms
7492acc9 401 :name "Microsoft"
78024f88 402 :font-lock sql-mode-ms-font-lock-keywords
7492acc9
MM
403 :sqli-program sql-ms-program
404 :sqli-options sql-ms-options
405 :sqli-login sql-ms-login-params
30c4d8dc 406 :sqli-comint-func sql-comint-ms
7492acc9
MM
407 :prompt-regexp "^[0-9]*>"
408 :prompt-length 5
fbcc67e2 409 :syntax-alist ((?@ . "_"))
7492acc9
MM
410 :terminator ("^go" . "go"))
411
78024f88 412 (mysql
55659495 413 :name "MySQL"
7492acc9 414 :free-software t
78024f88 415 :font-lock sql-mode-mysql-font-lock-keywords
7492acc9
MM
416 :sqli-program sql-mysql-program
417 :sqli-options sql-mysql-options
418 :sqli-login sql-mysql-login-params
30c4d8dc 419 :sqli-comint-func sql-comint-mysql
74790210
MM
420 :list-all "SHOW TABLES;"
421 :list-table "DESCRIBE %s;"
7492acc9
MM
422 :prompt-regexp "^mysql> "
423 :prompt-length 6
3bd2cfef 424 :prompt-cont-regexp "^ -> "
fbcc67e2 425 :syntax-alist ((?# . "< b"))
7492acc9
MM
426 :input-filter sql-remove-tabs-filter)
427
78024f88 428 (oracle
7492acc9 429 :name "Oracle"
78024f88 430 :font-lock sql-mode-oracle-font-lock-keywords
7492acc9
MM
431 :sqli-program sql-oracle-program
432 :sqli-options sql-oracle-options
433 :sqli-login sql-oracle-login-params
30c4d8dc 434 :sqli-comint-func sql-comint-oracle
fbcc67e2
MM
435 :list-all sql-oracle-list-all
436 :list-table sql-oracle-list-table
437 :completion-object sql-oracle-completion-object
7492acc9
MM
438 :prompt-regexp "^SQL> "
439 :prompt-length 5
fbcc67e2
MM
440 :prompt-cont-regexp "^\\s-*[[:digit:]]+ "
441 :statement sql-oracle-statement-starters
442 :syntax-alist ((?$ . "_") (?# . "_"))
443 :terminator ("\\(^/\\|;\\)$" . "/")
7492acc9
MM
444 :input-filter sql-placeholders-filter)
445
78024f88 446 (postgres
7492acc9
MM
447 :name "Postgres"
448 :free-software t
78024f88 449 :font-lock sql-mode-postgres-font-lock-keywords
7492acc9
MM
450 :sqli-program sql-postgres-program
451 :sqli-options sql-postgres-options
452 :sqli-login sql-postgres-login-params
30c4d8dc 453 :sqli-comint-func sql-comint-postgres
74790210
MM
454 :list-all ("\\d+" . "\\dS+")
455 :list-table ("\\d+ %s" . "\\dS+ %s")
fbcc67e2
MM
456 :completion-object sql-postgres-completion-object
457 :prompt-regexp "^\\w*=[#>] "
7492acc9 458 :prompt-length 5
fbcc67e2 459 :prompt-cont-regexp "^\\w*[-(][#>] "
7492acc9 460 :input-filter sql-remove-tabs-filter
fbcc67e2 461 :terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g"))
7492acc9 462
78024f88 463 (solid
7492acc9 464 :name "Solid"
78024f88 465 :font-lock sql-mode-solid-font-lock-keywords
7492acc9
MM
466 :sqli-program sql-solid-program
467 :sqli-options sql-solid-options
468 :sqli-login sql-solid-login-params
30c4d8dc 469 :sqli-comint-func sql-comint-solid
7492acc9
MM
470 :prompt-regexp "^"
471 :prompt-length 0)
472
78024f88 473 (sqlite
55659495 474 :name "SQLite"
7492acc9 475 :free-software t
78024f88 476 :font-lock sql-mode-sqlite-font-lock-keywords
7492acc9
MM
477 :sqli-program sql-sqlite-program
478 :sqli-options sql-sqlite-options
479 :sqli-login sql-sqlite-login-params
30c4d8dc 480 :sqli-comint-func sql-comint-sqlite
74790210
MM
481 :list-all ".tables"
482 :list-table ".schema %s"
fbcc67e2 483 :completion-object sql-sqlite-completion-object
7492acc9 484 :prompt-regexp "^sqlite> "
3bd2cfef 485 :prompt-length 8
fbcc67e2 486 :prompt-cont-regexp "^ \.\.\.> "
3bd2cfef 487 :terminator ";")
7492acc9 488
78024f88 489 (sybase
7492acc9 490 :name "Sybase"
78024f88 491 :font-lock sql-mode-sybase-font-lock-keywords
7492acc9
MM
492 :sqli-program sql-sybase-program
493 :sqli-options sql-sybase-options
494 :sqli-login sql-sybase-login-params
30c4d8dc 495 :sqli-comint-func sql-comint-sybase
7492acc9
MM
496 :prompt-regexp "^SQL> "
497 :prompt-length 5
fbcc67e2 498 :syntax-alist ((?@ . "_"))
7492acc9 499 :terminator ("^go" . "go"))
78024f88 500 )
7492acc9
MM
501 "An alist of product specific configuration settings.
502
503Without an entry in this list a product will not be properly
504highlighted and will not support `sql-interactive-mode'.
78024f88
AS
505
506Each element in the list is in the following format:
507
508 \(PRODUCT FEATURE VALUE ...)
509
7492acc9
MM
510where PRODUCT is the appropriate value of `sql-product'. The
511product name is then followed by FEATURE-VALUE pairs. If a
512FEATURE is not specified, its VALUE is treated as nil. FEATURE
513may be any one of the following:
514
515 :name string containing the displayable name of
516 the product.
517
518 :free-software is the product Free (as in Freedom) software?
78024f88
AS
519
520 :font-lock name of the variable containing the product
521 specific font lock highlighting patterns.
522
7492acc9
MM
523 :sqli-program name of the variable containing the product
524 specific interactive program name.
525
526 :sqli-options name of the variable containing the list
527 of product specific options.
78024f88 528
7492acc9
MM
529 :sqli-login name of the variable containing the list of
530 login parameters (i.e., user, password,
531 database and server) needed to connect to
532 the database.
533
30c4d8dc 534 :sqli-comint-func name of a function which accepts no
78024f88
AS
535 parameters that will use the values of
536 `sql-user', `sql-password',
fbcc67e2
MM
537 `sql-database', `sql-server' and
538 `sql-port' to open a comint buffer and
539 connect to the database. Do product
540 specific configuration of comint in this
541 function.
78024f88 542
74790210
MM
543 :list-all Command string or function which produces
544 a listing of all objects in the database.
545 If it's a cons cell, then the car
546 produces the standard list of objects and
547 the cdr produces an enhanced list of
548 objects. What \"enhanced\" means is
549 dependent on the SQL product and may not
550 exist. In general though, the
551 \"enhanced\" list should include visible
552 objects from other schemas.
553
554 :list-table Command string or function which produces
555 a detailed listing of a specific database
556 table. If its a cons cell, then the car
557 produces the standard list and the cdr
558 produces an enhanced list.
559
fbcc67e2
MM
560 :completion-object A function that returns a list of
561 objects. Called with a single
562 parameter--if nil then list objects
563 accessible in the current schema, if
564 not-nil it is the name of a schema whose
565 objects should be listed.
566
567 :completion-column A function that returns a list of
568 columns. Called with a single
569 parameter--if nil then list objects
570 accessible in the current schema, if
571 not-nil it is the name of a schema whose
572 objects should be listed.
573
7492acc9 574 :prompt-regexp regular expression string that matches
9fd8cb36 575 the prompt issued by the product
7492acc9
MM
576 interpreter.
577
578 :prompt-length length of the prompt on the line.
579
3bd2cfef
MM
580 :prompt-cont-regexp regular expression string that matches
581 the continuation prompt issued by the
582 product interpreter.
583
7492acc9
MM
584 :input-filter function which can filter strings sent to
585 the command interpreter. It is also used
586 by the `sql-send-string',
587 `sql-send-region', `sql-send-paragraph'
588 and `sql-send-buffer' functions. The
589 function is passed the string sent to the
590 command interpreter and must return the
3bd2cfef
MM
591 filtered string. May also be a list of
592 such functions.
7492acc9 593
fbcc67e2
MM
594 :statement name of a variable containing a regexp that
595 matches the beginning of SQL statements.
596
7492acc9
MM
597 :terminator the terminator to be sent after a
598 `sql-send-string', `sql-send-region',
599 `sql-send-paragraph' and
600 `sql-send-buffer' command. May be the
601 literal string or a cons of a regexp to
602 match an existing terminator in the
603 string and the terminator to be used if
604 its absent. By default \";\".
605
606 :syntax-alist alist of syntax table entries to enable
607 special character treatment by font-lock
608 and imenu.
609
610Other features can be stored but they will be ignored. However,
611you can develop new functionality which is product independent by
612using `sql-get-product-feature' to lookup the product specific
613settings.")
614
615(defvar sql-indirect-features
fbcc67e2 616 '(:font-lock :sqli-program :sqli-options :sqli-login :statement))
78024f88 617
30c4d8dc 618(defcustom sql-connection-alist nil
34e8a2da 619 "An alist of connection parameters for interacting with a SQL product.
30c4d8dc
MM
620Each element of the alist is as follows:
621
622 \(CONNECTION \(SQL-VARIABLE VALUE) ...)
623
624Where CONNECTION is a symbol identifying the connection, SQL-VARIABLE
625is the symbol name of a SQL mode variable, and VALUE is the value to
34e8a2da
GM
626be assigned to the variable. The most common SQL-VARIABLE settings
627associated with a connection are: `sql-product', `sql-user',
628`sql-password', `sql-port', `sql-server', and `sql-database'.
30c4d8dc
MM
629
630If a SQL-VARIABLE is part of the connection, it will not be
34e8a2da
GM
631prompted for during login. The command `sql-connect' starts a
632predefined SQLi session using the parameters from this list.
633Connections defined here appear in the submenu SQL->Start... for
634making new SQLi sessions."
d26b0ea9 635 :type `(alist :key-type (string :tag "Connection")
30c4d8dc
MM
636 :value-type
637 (set
638 (group (const :tag "Product" sql-product)
639 (choice
640 ,@(mapcar (lambda (prod-info)
641 `(const :tag
642 ,(or (plist-get (cdr prod-info) :name)
643 (capitalize (symbol-name (car prod-info))))
644 (quote ,(car prod-info))))
645 sql-product-alist)))
646 (group (const :tag "Username" sql-user) string)
647 (group (const :tag "Password" sql-password) string)
648 (group (const :tag "Server" sql-server) string)
649 (group (const :tag "Database" sql-database) string)
d26b0ea9
MM
650 (group (const :tag "Port" sql-port) integer)
651 (repeat :inline t
652 (list :tab "Other"
653 (symbol :tag " Variable Symbol")
654 (sexp :tag "Value Expression")))))
30c4d8dc
MM
655 :version "24.1"
656 :group 'SQL)
657
55659495 658(defcustom sql-product 'ansi
7492acc9 659 "Select the SQL database product used so that buffers can be
55659495
SM
660highlighted properly when you open them."
661 :type `(choice
662 ,@(mapcar (lambda (prod-info)
663 `(const :tag
664 ,(or (plist-get (cdr prod-info) :name)
665 (capitalize (symbol-name (car prod-info))))
666 ,(car prod-info)))
667 sql-product-alist))
30c4d8dc
MM
668 :group 'SQL
669 :safe 'symbolp)
9250002f 670(defvaralias 'sql-dialect 'sql-product)
7492acc9 671
91af3942 672;; misc customization of sql.el behavior
801d1cb0 673
9ef3882f
GM
674(defcustom sql-electric-stuff nil
675 "Treat some input as electric.
676If set to the symbol `semicolon', then hitting `;' will send current
677input in the SQLi buffer to the process.
678If set to the symbol `go', then hitting `go' on a line by itself will
679send current input in the SQLi buffer to the process.
680If set to nil, then you must use \\[comint-send-input] in order to send
681current input in the SQLi buffer to the process."
682 :type '(choice (const :tag "Nothing" nil)
063c6324 683 (const :tag "The semicolon `;'" semicolon)
9ef3882f
GM
684 (const :tag "The string `go' by itself" go))
685 :version "20.8"
686 :group 'SQL)
687
7492acc9
MM
688(defcustom sql-send-terminator nil
689 "When non-nil, add a terminator to text sent to the SQL interpreter.
690
691When text is sent to the SQL interpreter (via `sql-send-string',
692`sql-send-region', `sql-send-paragraph' or `sql-send-buffer'), a
693command terminator can be automatically sent as well. The
694terminator is not sent, if the string sent already ends with the
695terminator.
696
697If this value is t, then the default command terminator for the
698SQL interpreter is sent. If this value is a string, then the
699string is sent.
700
701If the value is a cons cell of the form (PAT . TERM), then PAT is
702a regexp used to match the terminator in the string and TERM is
703the terminator to be sent. This form is useful if the SQL
704interpreter has more than one way of submitting a SQL command.
705The PAT regexp can match any of them, and TERM is the way we do
706it automatically."
707
708 :type '(choice (const :tag "No Terminator" nil)
709 (const :tag "Default Terminator" t)
710 (string :tag "Terminator String")
711 (cons :tag "Terminator Pattern and String"
712 (string :tag "Terminator Pattern")
713 (string :tag "Terminator String")))
714 :version "22.2"
715 :group 'SQL)
95e4b2ef 716
fbcc67e2
MM
717(defvar sql-contains-names nil
718 "When non-nil, the current buffer contains database names.
719
720Globally should be set to nil; it will be non-nil in `sql-mode',
721`sql-interactive-mode' and list all buffers.")
722
723
7492acc9
MM
724(defcustom sql-pop-to-buffer-after-send-region nil
725 "When non-nil, pop to the buffer SQL statements are sent to.
726
727After a call to `sql-sent-string', `sql-send-region',
728`sql-send-paragraph' or `sql-send-buffer', the window is split
729and the SQLi buffer is shown. If this variable is not nil, that
730buffer's window will be selected by calling `pop-to-buffer'. If
731this variable is nil, that buffer is shown using
732`display-buffer'."
c7055d66
RS
733 :type 'boolean
734 :group 'SQL)
735
801d1cb0
AS
736;; imenu support for sql-mode.
737
738(defvar sql-imenu-generic-expression
78024f88 739 ;; Items are in reverse order because they are rendered in reverse.
9fd8cb36
SM
740 '(("Rules/Defaults" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(rule\\|default\\)\\s-+\\(\\w+\\)" 3)
741 ("Sequences" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*sequence\\s-+\\(\\w+\\)" 2)
742 ("Triggers" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*trigger\\s-+\\(\\w+\\)" 2)
743 ("Functions" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?function\\s-+\\(\\w+\\)" 3)
744 ("Procedures" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4)
745 ("Packages" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3)
7492acc9 746 ("Types" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*type\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3)
9fd8cb36
SM
747 ("Indexes" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*index\\s-+\\(\\w+\\)" 2)
748 ("Tables/Views" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(table\\|view\\)\\s-+\\(\\w+\\)" 3))
801d1cb0
AS
749 "Define interesting points in the SQL buffer for `imenu'.
750
9ef3882f 751This is used to set `imenu-generic-expression' when SQL mode is
063c6324
JB
752entered. Subsequent changes to `sql-imenu-generic-expression' will
753not affect existing SQL buffers because imenu-generic-expression is
754a local variable.")
801d1cb0
AS
755
756;; history file
757
c7055d66 758(defcustom sql-input-ring-file-name nil
7492acc9 759 "If non-nil, name of the file to read/write input history.
c7055d66 760
9ef73b91
KH
761You have to set this variable if you want the history of your commands
762saved from one Emacs session to the next. If this variable is set,
763exiting the SQL interpreter in an SQLi buffer will write the input
764history to the specified file. Starting a new process in a SQLi buffer
765will read the input history from the specified file.
766
77d352a6
GM
767This is used to initialize `comint-input-ring-file-name'.
768
769Note that the size of the input history is determined by the variable
770`comint-input-ring-size'."
c7055d66
RS
771 :type '(choice (const :tag "none" nil)
772 (file))
773 :group 'SQL)
774
775(defcustom sql-input-ring-separator "\n--\n"
7492acc9 776 "Separator between commands in the history file.
c7055d66
RS
777
778If set to \"\\n\", each line in the history file will be interpreted as
779one command. Multi-line commands are split into several commands when
780the input ring is initialized from a history file.
781
77d352a6
GM
782This variable used to initialize `comint-input-ring-separator'.
783`comint-input-ring-separator' is part of Emacs 21; if your Emacs
784does not have it, setting `sql-input-ring-separator' will have no
785effect. In that case multiline commands will be split into several
786commands when the input history is read, as if you had set
787`sql-input-ring-separator' to \"\\n\"."
95e4b2ef
RS
788 :type 'string
789 :group 'SQL)
790
791;; The usual hooks
792
793(defcustom sql-interactive-mode-hook '()
7492acc9 794 "Hook for customizing `sql-interactive-mode'."
95e4b2ef
RS
795 :type 'hook
796 :group 'SQL)
797
798(defcustom sql-mode-hook '()
7492acc9 799 "Hook for customizing `sql-mode'."
95e4b2ef
RS
800 :type 'hook
801 :group 'SQL)
802
c7055d66 803(defcustom sql-set-sqli-hook '()
7492acc9 804 "Hook for reacting to changes of `sql-buffer'.
c7055d66
RS
805
806This is called by `sql-set-sqli-buffer' when the value of `sql-buffer'
807is changed."
808 :type 'hook
809 :group 'SQL)
810
bb5aa5d6
MM
811(defcustom sql-login-hook '()
812 "Hook for interacting with a buffer in `sql-interactive-mode'.
813
814This hook is invoked in a buffer once it is ready to accept input
815for the first time."
2bed3f04 816 :version "24.1"
bb5aa5d6
MM
817 :type 'hook
818 :group 'SQL)
819
fbcc67e2
MM
820;; Customization for ANSI
821
822(defcustom sql-ansi-statement-starters (regexp-opt '(
823 "create" "alter" "drop"
824 "select" "insert" "update" "delete" "merge"
825 "grant" "revoke"
826))
827 "Regexp of keywords that start SQL commands
828
829All products share this list; products should define a regexp to
830identify additional keywords in a variable defined by
5fec1b8e 831the :statement feature."
2bed3f04 832 :version "24.1"
5fec1b8e
GM
833 :type 'string
834 :group 'SQL)
fbcc67e2 835
eb3f61dd 836;; Customization for Oracle
95e4b2ef
RS
837
838(defcustom sql-oracle-program "sqlplus"
7492acc9 839 "Command to start sqlplus by Oracle.
95e4b2ef
RS
840
841Starts `sql-interactive-mode' after doing some setup.
842
c38762fd
JB
843On Windows, \"sqlplus\" usually starts the sqlplus \"GUI\". In order
844to start the sqlplus console, use \"plus33\" or something similar.
845You will find the file in your Orant\\bin directory."
a081a529
RS
846 :type 'file
847 :group 'SQL)
848
9ef3882f 849(defcustom sql-oracle-options nil
7492acc9 850 "List of additional options for `sql-oracle-program'."
9ef3882f
GM
851 :type '(repeat string)
852 :version "20.8"
853 :group 'SQL)
854
7492acc9
MM
855(defcustom sql-oracle-login-params '(user password database)
856 "List of login parameters needed to connect to Oracle."
5474c40f 857 :type 'sql-login-params
7492acc9
MM
858 :version "24.1"
859 :group 'SQL)
860
5fec1b8e
GM
861(defcustom sql-oracle-statement-starters
862 (regexp-opt '("declare" "begin" "with"))
863 "Additional statement starting keywords in Oracle."
2bed3f04 864 :version "24.1"
5fec1b8e
GM
865 :type 'string
866 :group 'SQL)
fbcc67e2 867
7492acc9
MM
868(defcustom sql-oracle-scan-on t
869 "Non-nil if placeholders should be replaced in Oracle SQLi.
870
871When non-nil, Emacs will scan text sent to sqlplus and prompt
872for replacement text for & placeholders as sqlplus does. This
fbcc67e2 873is needed on Windows where SQL*Plus output is buffered and the
7492acc9
MM
874prompts are not shown until after the text is entered.
875
fbcc67e2
MM
876You need to issue the following command in SQL*Plus to be safe:
877
878 SET DEFINE OFF
7492acc9 879
fbcc67e2 880In older versions of SQL*Plus, this was the SET SCAN OFF command."
2bed3f04 881 :version "24.1"
7492acc9
MM
882 :type 'boolean
883 :group 'SQL)
884
04e082b0
MM
885(defcustom sql-db2-escape-newlines nil
886 "Non-nil if newlines should be escaped by a backslash in DB2 SQLi.
887
888When non-nil, Emacs will automatically insert a space and
889backslash prior to every newline in multi-line SQL statements as
890they are submitted to an interactive DB2 session."
891 :version "24.3"
892 :type 'boolean
893 :group 'SQL)
894
5d538ce3
JB
895;; Customization for SQLite
896
9250002f
MM
897(defcustom sql-sqlite-program (or (executable-find "sqlite3")
898 (executable-find "sqlite")
899 "sqlite")
7492acc9 900 "Command to start SQLite.
5d538ce3 901
7492acc9 902Starts `sql-interactive-mode' after doing some setup."
5d538ce3
JB
903 :type 'file
904 :group 'SQL)
905
906(defcustom sql-sqlite-options nil
7492acc9 907 "List of additional options for `sql-sqlite-program'."
5d538ce3
JB
908 :type '(repeat string)
909 :version "20.8"
910 :group 'SQL)
911
9250002f 912(defcustom sql-sqlite-login-params '((database :file ".*\\.\\(db\\|sqlite[23]?\\)"))
7492acc9 913 "List of login parameters needed to connect to SQLite."
5474c40f 914 :type 'sql-login-params
7492acc9
MM
915 :version "24.1"
916 :group 'SQL)
917
fbcc67e2 918;; Customization for MySQL
a081a529
RS
919
920(defcustom sql-mysql-program "mysql"
7492acc9 921 "Command to start mysql by TcX.
a081a529 922
7492acc9 923Starts `sql-interactive-mode' after doing some setup."
dab100d7
RS
924 :type 'file
925 :group 'SQL)
926
542c6552 927(defcustom sql-mysql-options nil
7492acc9 928 "List of additional options for `sql-mysql-program'.
524c8caf
GM
929The following list of options is reported to make things work
930on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
542c6552
GM
931 :type '(repeat string)
932 :version "20.8"
933 :group 'SQL)
934
7492acc9 935(defcustom sql-mysql-login-params '(user password database server)
fbcc67e2 936 "List of login parameters needed to connect to MySQL."
5474c40f 937 :type 'sql-login-params
7492acc9
MM
938 :version "24.1"
939 :group 'SQL)
940
eb3f61dd 941;; Customization for Solid
dab100d7
RS
942
943(defcustom sql-solid-program "solsql"
7492acc9 944 "Command to start SOLID SQL Editor.
dab100d7 945
7492acc9 946Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
947 :type 'file
948 :group 'SQL)
949
7492acc9
MM
950(defcustom sql-solid-login-params '(user password server)
951 "List of login parameters needed to connect to Solid."
5474c40f 952 :type 'sql-login-params
7492acc9
MM
953 :version "24.1"
954 :group 'SQL)
955
c38762fd 956;; Customization for Sybase
95e4b2ef
RS
957
958(defcustom sql-sybase-program "isql"
c38762fd 959 "Command to start isql by Sybase.
95e4b2ef 960
7492acc9 961Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
962 :type 'file
963 :group 'SQL)
964
9b5360aa 965(defcustom sql-sybase-options nil
7492acc9 966 "List of additional options for `sql-sybase-program'.
9b5360aa
GM
967Some versions of isql might require the -n option in order to work."
968 :type '(repeat string)
969 :version "20.8"
970 :group 'SQL)
971
7492acc9
MM
972(defcustom sql-sybase-login-params '(server user password database)
973 "List of login parameters needed to connect to Sybase."
5474c40f 974 :type 'sql-login-params
7492acc9
MM
975 :version "24.1"
976 :group 'SQL)
977
eb3f61dd 978;; Customization for Informix
95e4b2ef
RS
979
980(defcustom sql-informix-program "dbaccess"
7492acc9 981 "Command to start dbaccess by Informix.
95e4b2ef 982
7492acc9 983Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
984 :type 'file
985 :group 'SQL)
986
7492acc9
MM
987(defcustom sql-informix-login-params '(database)
988 "List of login parameters needed to connect to Informix."
5474c40f 989 :type 'sql-login-params
7492acc9
MM
990 :version "24.1"
991 :group 'SQL)
992
eb3f61dd 993;; Customization for Ingres
95e4b2ef
RS
994
995(defcustom sql-ingres-program "sql"
7492acc9 996 "Command to start sql by Ingres.
95e4b2ef 997
7492acc9 998Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
999 :type 'file
1000 :group 'SQL)
1001
7492acc9
MM
1002(defcustom sql-ingres-login-params '(database)
1003 "List of login parameters needed to connect to Ingres."
5474c40f 1004 :type 'sql-login-params
7492acc9
MM
1005 :version "24.1"
1006 :group 'SQL)
1007
eb3f61dd 1008;; Customization for Microsoft
95e4b2ef 1009
78024f88 1010(defcustom sql-ms-program "osql"
7492acc9 1011 "Command to start osql by Microsoft.
95e4b2ef 1012
7492acc9 1013Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
1014 :type 'file
1015 :group 'SQL)
1016
f4df536d
JB
1017(defcustom sql-ms-options '("-w" "300" "-n")
1018 ;; -w is the linesize
7492acc9 1019 "List of additional options for `sql-ms-program'."
f4df536d 1020 :type '(repeat string)
bf247b6e 1021 :version "22.1"
f4df536d
JB
1022 :group 'SQL)
1023
7492acc9
MM
1024(defcustom sql-ms-login-params '(user password server database)
1025 "List of login parameters needed to connect to Microsoft."
5474c40f 1026 :type 'sql-login-params
7492acc9
MM
1027 :version "24.1"
1028 :group 'SQL)
1029
eb3f61dd 1030;; Customization for Postgres
95e4b2ef
RS
1031
1032(defcustom sql-postgres-program "psql"
801d1cb0 1033 "Command to start psql by Postgres.
95e4b2ef 1034
7492acc9 1035Starts `sql-interactive-mode' after doing some setup."
95e4b2ef
RS
1036 :type 'file
1037 :group 'SQL)
1038
524c8caf 1039(defcustom sql-postgres-options '("-P" "pager=off")
7492acc9 1040 "List of additional options for `sql-postgres-program'.
aa88e662
GM
1041The default setting includes the -P option which breaks older versions
1042of the psql client (such as version 6.5.3). The -P option is equivalent
1043to the --pset option. If you want the psql to prompt you for a user
1044name, add the string \"-u\" to the list of options. If you want to
1045provide a user name on the command line (newer versions such as 7.1),
1046add your name with a \"-U\" prefix (such as \"-Umark\") to the list."
311e7a89
GM
1047 :type '(repeat string)
1048 :version "20.8"
1049 :group 'SQL)
1050
74790210
MM
1051(defcustom sql-postgres-login-params `((user :default ,(user-login-name))
1052 (database :default ,(user-login-name))
1053 server)
7492acc9 1054 "List of login parameters needed to connect to Postgres."
5474c40f 1055 :type 'sql-login-params
7492acc9
MM
1056 :version "24.1"
1057 :group 'SQL)
1058
eb3f61dd
GM
1059;; Customization for Interbase
1060
1061(defcustom sql-interbase-program "isql"
7492acc9 1062 "Command to start isql by Interbase.
eb3f61dd 1063
7492acc9 1064Starts `sql-interactive-mode' after doing some setup."
eb3f61dd
GM
1065 :type 'file
1066 :group 'SQL)
1067
1068(defcustom sql-interbase-options nil
7492acc9 1069 "List of additional options for `sql-interbase-program'."
eb3f61dd
GM
1070 :type '(repeat string)
1071 :version "20.8"
1072 :group 'SQL)
1073
7492acc9
MM
1074(defcustom sql-interbase-login-params '(user password database)
1075 "List of login parameters needed to connect to Interbase."
5474c40f 1076 :type 'sql-login-params
7492acc9
MM
1077 :version "24.1"
1078 :group 'SQL)
1079
624ef9b3
GM
1080;; Customization for DB2
1081
1082(defcustom sql-db2-program "db2"
7492acc9 1083 "Command to start db2 by IBM.
624ef9b3 1084
7492acc9 1085Starts `sql-interactive-mode' after doing some setup."
624ef9b3
GM
1086 :type 'file
1087 :group 'SQL)
1088
1089(defcustom sql-db2-options nil
7492acc9 1090 "List of additional options for `sql-db2-program'."
624ef9b3
GM
1091 :type '(repeat string)
1092 :version "20.8"
1093 :group 'SQL)
1094
7492acc9
MM
1095(defcustom sql-db2-login-params nil
1096 "List of login parameters needed to connect to DB2."
5474c40f 1097 :type 'sql-login-params
7492acc9
MM
1098 :version "24.1"
1099 :group 'SQL)
1100
f4df536d
JB
1101;; Customization for Linter
1102
1103(defcustom sql-linter-program "inl"
7492acc9 1104 "Command to start inl by RELEX.
f4df536d
JB
1105
1106Starts `sql-interactive-mode' after doing some setup."
1107 :type 'file
1108 :group 'SQL)
1109
1110(defcustom sql-linter-options nil
7492acc9 1111 "List of additional options for `sql-linter-program'."
f4df536d
JB
1112 :type '(repeat string)
1113 :version "21.3"
1114 :group 'SQL)
1115
7492acc9
MM
1116(defcustom sql-linter-login-params '(user password database server)
1117 "Login parameters to needed to connect to Linter."
5474c40f 1118 :type 'sql-login-params
7492acc9
MM
1119 :version "24.1"
1120 :group 'SQL)
1121
95e4b2ef
RS
1122\f
1123
1124;;; Variables which do not need customization
1125
1126(defvar sql-user-history nil
1127 "History of usernames used.")
1128
1129(defvar sql-database-history nil
1130 "History of databases used.")
1131
1132(defvar sql-server-history nil
1133 "History of servers used.")
1134
1135;; Passwords are not kept in a history.
1136
74790210
MM
1137(defvar sql-product-history nil
1138 "History of products used.")
1139
1140(defvar sql-connection-history nil
1141 "History of connections used.")
1142
95e4b2ef 1143(defvar sql-buffer nil
dab100d7
RS
1144 "Current SQLi buffer.
1145
063c6324 1146The global value of `sql-buffer' is the name of the latest SQLi buffer
dab100d7
RS
1147created. Any SQL buffer created will make a local copy of this value.
1148See `sql-interactive-mode' for more on multiple sessions. If you want
1149to change the SQLi buffer a SQL mode sends its SQL strings to, change
c7055d66 1150the local value of `sql-buffer' using \\[sql-set-sqli-buffer].")
95e4b2ef
RS
1151
1152(defvar sql-prompt-regexp nil
1153 "Prompt used to initialize `comint-prompt-regexp'.
1154
78024f88 1155You can change `sql-prompt-regexp' on `sql-interactive-mode-hook'.")
95e4b2ef 1156
a081a529
RS
1157(defvar sql-prompt-length 0
1158 "Prompt used to set `left-margin' in `sql-interactive-mode'.
1159
78024f88 1160You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
a081a529 1161
3bd2cfef
MM
1162(defvar sql-prompt-cont-regexp nil
1163 "Prompt pattern of statement continuation prompts.")
1164
c7055d66
RS
1165(defvar sql-alternate-buffer-name nil
1166 "Buffer-local string used to possibly rename the SQLi buffer.
1167
1168Used by `sql-rename-buffer'.")
1169
fbcc67e2 1170(defun sql-buffer-live-p (buffer &optional product connection)
a386ac70
MM
1171 "Returns non-nil if the process associated with buffer is live.
1172
1173BUFFER can be a buffer object or a buffer name. The buffer must
1174be a live buffer, have an running process attached to it, be in
fbcc67e2
MM
1175`sql-interactive-mode', and, if PRODUCT or CONNECTION are
1176specified, it's `sql-product' or `sql-connection' must match."
a386ac70
MM
1177
1178 (when buffer
1179 (setq buffer (get-buffer buffer))
1180 (and buffer
1181 (buffer-live-p buffer)
1182 (get-buffer-process buffer)
1183 (comint-check-proc buffer)
1184 (with-current-buffer buffer
74790210 1185 (and (derived-mode-p 'sql-interactive-mode)
a386ac70 1186 (or (not product)
fbcc67e2
MM
1187 (eq product sql-product))
1188 (or (not connection)
1189 (eq connection sql-connection)))))))
9250002f 1190
9ef3882f
GM
1191;; Keymap for sql-interactive-mode.
1192
f4df536d 1193(defvar sql-interactive-mode-map
9ef3882f 1194 (let ((map (make-sparse-keymap)))
8d68e9b5 1195 (if (fboundp 'set-keymap-parent)
9ef3882f 1196 (set-keymap-parent map comint-mode-map); Emacs
8d68e9b5
RS
1197 (if (fboundp 'set-keymap-parents)
1198 (set-keymap-parents map (list comint-mode-map)))); XEmacs
1199 (if (fboundp 'set-keymap-name)
9ef3882f
GM
1200 (set-keymap-name map 'sql-interactive-mode-map)); XEmacs
1201 (define-key map (kbd "C-j") 'sql-accumulate-and-indent)
1202 (define-key map (kbd "C-c C-w") 'sql-copy-column)
1203 (define-key map (kbd "O") 'sql-magic-go)
1204 (define-key map (kbd "o") 'sql-magic-go)
1205 (define-key map (kbd ";") 'sql-magic-semicolon)
74790210
MM
1206 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1207 (define-key map (kbd "C-c C-l t") 'sql-list-table)
9ef3882f
GM
1208 map)
1209 "Mode map used for `sql-interactive-mode'.
1210Based on `comint-mode-map'.")
95e4b2ef
RS
1211
1212;; Keymap for sql-mode.
1213
1214(defvar sql-mode-map
1215 (let ((map (make-sparse-keymap)))
9ef3882f
GM
1216 (define-key map (kbd "C-c C-c") 'sql-send-paragraph)
1217 (define-key map (kbd "C-c C-r") 'sql-send-region)
9fd8cb36 1218 (define-key map (kbd "C-c C-s") 'sql-send-string)
9ef3882f 1219 (define-key map (kbd "C-c C-b") 'sql-send-buffer)
7492acc9 1220 (define-key map (kbd "C-c C-i") 'sql-product-interactive)
74790210
MM
1221 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1222 (define-key map (kbd "C-c C-l t") 'sql-list-table)
fbcc67e2
MM
1223 (define-key map [remap beginning-of-defun] 'sql-beginning-of-statement)
1224 (define-key map [remap end-of-defun] 'sql-end-of-statement)
95e4b2ef
RS
1225 map)
1226 "Mode map used for `sql-mode'.")
1227
1228;; easy menu for sql-mode.
1229
801d1cb0
AS
1230(easy-menu-define
1231 sql-mode-menu sql-mode-map
95e4b2ef 1232 "Menu for `sql-mode'."
55659495 1233 `("SQL"
9250002f 1234 ["Send Paragraph" sql-send-paragraph (sql-buffer-live-p sql-buffer)]
7492acc9 1235 ["Send Region" sql-send-region (and mark-active
9250002f
MM
1236 (sql-buffer-live-p sql-buffer))]
1237 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)]
1238 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)]
d26b0ea9 1239 "--"
fbcc67e2
MM
1240 ["List all objects" sql-list-all (and (sql-buffer-live-p sql-buffer)
1241 (sql-get-product-feature sql-product :list-all))]
1242 ["List table details" sql-list-table (and (sql-buffer-live-p sql-buffer)
1243 (sql-get-product-feature sql-product :list-table))]
74790210 1244 "--"
d26b0ea9
MM
1245 ["Start SQLi session" sql-product-interactive
1246 :visible (not sql-connection-alist)
1247 :enable (sql-get-product-feature sql-product :sqli-comint-func)]
1248 ("Start..."
1249 :visible sql-connection-alist
1250 :filter sql-connection-menu-filter
1251 "--"
1252 ["New SQLi Session" sql-product-interactive (sql-get-product-feature sql-product :sqli-comint-func)])
1253 ["--"
1254 :visible sql-connection-alist]
dab100d7 1255 ["Show SQLi buffer" sql-show-sqli-buffer t]
c7055d66 1256 ["Set SQLi buffer" sql-set-sqli-buffer t]
801d1cb0 1257 ["Pop to SQLi buffer after send"
95e4b2ef
RS
1258 sql-toggle-pop-to-buffer-after-send-region
1259 :style toggle
624ef9b3 1260 :selected sql-pop-to-buffer-after-send-region]
78024f88
AS
1261 ["--" nil nil]
1262 ("Product"
55659495
SM
1263 ,@(mapcar (lambda (prod-info)
1264 (let* ((prod (pop prod-info))
1265 (name (or (plist-get prod-info :name)
1266 (capitalize (symbol-name prod))))
1267 (cmd (intern (format "sql-highlight-%s-keywords" prod))))
1268 (fset cmd `(lambda () ,(format "Highlight %s SQL keywords." name)
1269 (interactive)
1270 (sql-set-product ',prod)))
1271 (vector name cmd
1272 :style 'radio
1273 :selected `(eq sql-product ',prod))))
1274 sql-product-alist))))
95e4b2ef 1275
c7055d66
RS
1276;; easy menu for sql-interactive-mode.
1277
801d1cb0 1278(easy-menu-define
c7055d66
RS
1279 sql-interactive-mode-menu sql-interactive-mode-map
1280 "Menu for `sql-interactive-mode'."
1281 '("SQL"
d26b0ea9 1282 ["Rename Buffer" sql-rename-buffer t]
74790210
MM
1283 ["Save Connection" sql-save-connection (not sql-connection)]
1284 "--"
fbcc67e2
MM
1285 ["List all objects" sql-list-all (sql-get-product-feature sql-product :list-all)]
1286 ["List table details" sql-list-table (sql-get-product-feature sql-product :list-table)]))
c7055d66 1287
95e4b2ef
RS
1288;; Abbreviations -- if you want more of them, define them in your
1289;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
1290
1291(defvar sql-mode-abbrev-table nil
1292 "Abbrev table used in `sql-mode' and `sql-interactive-mode'.")
9fd8cb36 1293(unless sql-mode-abbrev-table
e5a4bf48
GM
1294 (define-abbrev-table 'sql-mode-abbrev-table nil))
1295
f77183c0 1296(mapc
01295a22 1297 ;; In Emacs 22+, provide SYSTEM-FLAG to define-abbrev.
4f91a816
SM
1298 (lambda (abbrev)
1299 (let ((name (car abbrev))
1300 (expansion (cdr abbrev)))
1301 (condition-case nil
1302 (define-abbrev sql-mode-abbrev-table name expansion nil 0 t)
1303 (error
1304 (define-abbrev sql-mode-abbrev-table name expansion)))))
01295a22
RS
1305 '(("ins" . "insert")
1306 ("upd" . "update")
1307 ("del" . "delete")
1308 ("sel" . "select")
1309 ("proc" . "procedure")
1310 ("func" . "function")
1311 ("cr" . "create")))
95e4b2ef
RS
1312
1313;; Syntax Table
1314
801d1cb0 1315(defvar sql-mode-syntax-table
95e4b2ef
RS
1316 (let ((table (make-syntax-table)))
1317 ;; C-style comments /**/ (see elisp manual "Syntax Flags"))
1318 (modify-syntax-entry ?/ ". 14" table)
1319 (modify-syntax-entry ?* ". 23" table)
01295a22 1320 ;; double-dash starts comments
9a9069c9 1321 (modify-syntax-entry ?- ". 12b" table)
01295a22 1322 ;; newline and formfeed end comments
95e4b2ef
RS
1323 (modify-syntax-entry ?\n "> b" table)
1324 (modify-syntax-entry ?\f "> b" table)
01295a22 1325 ;; single quotes (') delimit strings
a081a529 1326 (modify-syntax-entry ?' "\"" table)
01295a22
RS
1327 ;; double quotes (") don't delimit strings
1328 (modify-syntax-entry ?\" "." table)
fbcc67e2
MM
1329 ;; Make these all punctuation
1330 (mapc (lambda (c) (modify-syntax-entry c "." table))
1331 (string-to-list "!#$%&+,.:;<=>?@\\|"))
95e4b2ef
RS
1332 table)
1333 "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
1334
1335;; Font lock support
1336
78024f88 1337(defvar sql-mode-font-lock-object-name
01295a22
RS
1338 (eval-when-compile
1339 (list (concat "^\\s-*\\(?:create\\|drop\\|alter\\)\\s-+" ;; lead off with CREATE, DROP or ALTER
1340 "\\(?:\\w+\\s-+\\)*" ;; optional intervening keywords
1341 "\\(?:table\\|view\\|\\(?:package\\|type\\)\\(?:\\s-+body\\)?\\|proc\\(?:edure\\)?"
1342 "\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+"
1343 "\\(\\w+\\)")
1344 1 'font-lock-function-name-face))
9fd8cb36
SM
1345
1346 "Pattern to match the names of top-level objects.
1347
1348The pattern matches the name in a CREATE, DROP or ALTER
1349statement. The format of variable should be a valid
1350`font-lock-keywords' entry.")
1351
7492acc9
MM
1352;; While there are international and American standards for SQL, they
1353;; are not followed closely, and most vendors offer significant
1354;; capabilities beyond those defined in the standard specifications.
1355
e4769531
PE
1356;; SQL mode provides support for highlighting based on the product. In
1357;; addition to highlighting the product keywords, any ANSI keywords not
1358;; used by the product are also highlighted. This will help identify
7492acc9
MM
1359;; keywords that could be restricted in future versions of the product
1360;; or might be a problem if ported to another product.
1361
1362;; To reduce the complexity and size of the regular expressions
1363;; generated to match keywords, ANSI keywords are filtered out of
1364;; product keywords if they are equivalent. To do this, we define a
1365;; function `sql-font-lock-keywords-builder' that removes any keywords
1366;; that are matched by the ANSI patterns and results in the same face
1367;; being applied. For this to work properly, we must play some games
1368;; with the execution and compile time behavior. This code is a
1369;; little tricky but works properly.
1370
1371;; When defining the keywords for individual products you should
1372;; include all of the keywords that you want matched. The filtering
1373;; against the ANSI keywords will be automatic if you use the
1374;; `sql-font-lock-keywords-builder' function and follow the
1375;; implementation pattern used for the other products in this file.
78024f88 1376
7492acc9
MM
1377(eval-when-compile
1378 (defvar sql-mode-ansi-font-lock-keywords)
1379 (setq sql-mode-ansi-font-lock-keywords nil))
1380
1381(eval-and-compile
1382 (defun sql-font-lock-keywords-builder (face boundaries &rest keywords)
1383 "Generation of regexp matching any one of KEYWORDS."
1384
1385 (let ((bdy (or boundaries '("\\b" . "\\b")))
1386 kwd)
1387
1388 ;; Remove keywords that are defined in ANSI
1389 (setq kwd keywords)
fbcc67e2
MM
1390 ;; (dolist (k keywords)
1391 ;; (catch 'next
1392 ;; (dolist (a sql-mode-ansi-font-lock-keywords)
1393 ;; (when (and (eq face (cdr a))
1394 ;; (eq (string-match (car a) k 0) 0)
1395 ;; (eq (match-end 0) (length k)))
1396 ;; (setq kwd (delq k kwd))
1397 ;; (throw 'next nil)))))
7492acc9
MM
1398
1399 ;; Create a properly formed font-lock-keywords item
1400 (cons (concat (car bdy)
1401 (regexp-opt kwd t)
1402 (cdr bdy))
fbcc67e2
MM
1403 face)))
1404
1405 (defun sql-regexp-abbrev (keyword)
1406 (let ((brk (string-match "[~]" keyword))
1407 (len (length keyword))
1408 (sep "\\(?:")
1409 re i)
1410 (if (not brk)
1411 keyword
1412 (setq re (substring keyword 0 brk)
1413 i (+ 2 brk)
1414 brk (1+ brk))
1415 (while (<= i len)
1416 (setq re (concat re sep (substring keyword brk i))
1417 sep "\\|"
1418 i (1+ i)))
1419 (concat re "\\)?"))))
1420
1421 (defun sql-regexp-abbrev-list (&rest keyw-list)
1422 (let ((re nil)
1423 (sep "\\<\\(?:"))
1424 (while keyw-list
1425 (setq re (concat re sep (sql-regexp-abbrev (car keyw-list)))
1426 sep "\\|"
1427 keyw-list (cdr keyw-list)))
1428 (concat re "\\)\\>"))))
9fd8cb36 1429
7492acc9
MM
1430(eval-when-compile
1431 (setq sql-mode-ansi-font-lock-keywords
1432 (list
1433 ;; ANSI Non Reserved keywords
1434 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
9fd8cb36
SM
1435"ada" "asensitive" "assignment" "asymmetric" "atomic" "between"
1436"bitvar" "called" "catalog_name" "chain" "character_set_catalog"
1437"character_set_name" "character_set_schema" "checked" "class_origin"
1438"cobol" "collation_catalog" "collation_name" "collation_schema"
1439"column_name" "command_function" "command_function_code" "committed"
1440"condition_number" "connection_name" "constraint_catalog"
1441"constraint_name" "constraint_schema" "contains" "cursor_name"
1442"datetime_interval_code" "datetime_interval_precision" "defined"
1443"definer" "dispatch" "dynamic_function" "dynamic_function_code"
1444"existing" "exists" "final" "fortran" "generated" "granted"
1445"hierarchy" "hold" "implementation" "infix" "insensitive" "instance"
1446"instantiable" "invoker" "key_member" "key_type" "length" "m"
1447"message_length" "message_octet_length" "message_text" "method" "more"
1448"mumps" "name" "nullable" "number" "options" "overlaps" "overriding"
1449"parameter_mode" "parameter_name" "parameter_ordinal_position"
1450"parameter_specific_catalog" "parameter_specific_name"
1451"parameter_specific_schema" "pascal" "pli" "position" "repeatable"
1452"returned_length" "returned_octet_length" "returned_sqlstate"
1453"routine_catalog" "routine_name" "routine_schema" "row_count" "scale"
1454"schema_name" "security" "self" "sensitive" "serializable"
1455"server_name" "similar" "simple" "source" "specific_name" "style"
1456"subclass_origin" "sublist" "symmetric" "system" "table_name"
1457"transaction_active" "transactions_committed"
1458"transactions_rolled_back" "transform" "transforms" "trigger_catalog"
1459"trigger_name" "trigger_schema" "type" "uncommitted" "unnamed"
1460"user_defined_type_catalog" "user_defined_type_name"
1461"user_defined_type_schema"
7492acc9 1462)
fbcc67e2 1463
7492acc9
MM
1464 ;; ANSI Reserved keywords
1465 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
9fd8cb36
SM
1466"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all"
1467"allocate" "alter" "and" "any" "are" "as" "asc" "assertion" "at"
1468"authorization" "before" "begin" "both" "breadth" "by" "call"
1469"cascade" "cascaded" "case" "catalog" "check" "class" "close"
1470"collate" "collation" "column" "commit" "completion" "connect"
1471"connection" "constraint" "constraints" "constructor" "continue"
1472"corresponding" "create" "cross" "cube" "current" "cursor" "cycle"
1473"data" "day" "deallocate" "declare" "default" "deferrable" "deferred"
1474"delete" "depth" "deref" "desc" "describe" "descriptor" "destroy"
1475"destructor" "deterministic" "diagnostics" "dictionary" "disconnect"
1476"distinct" "domain" "drop" "dynamic" "each" "else" "end" "equals"
1477"escape" "every" "except" "exception" "exec" "execute" "external"
1478"false" "fetch" "first" "for" "foreign" "found" "free" "from" "full"
1479"function" "general" "get" "global" "go" "goto" "grant" "group"
1480"grouping" "having" "host" "hour" "identity" "ignore" "immediate" "in"
1481"indicator" "initialize" "initially" "inner" "inout" "input" "insert"
1482"intersect" "into" "is" "isolation" "iterate" "join" "key" "language"
1483"last" "lateral" "leading" "left" "less" "level" "like" "limit"
1484"local" "locator" "map" "match" "minute" "modifies" "modify" "module"
1485"month" "names" "natural" "new" "next" "no" "none" "not" "null" "of"
1486"off" "old" "on" "only" "open" "operation" "option" "or" "order"
1487"ordinality" "out" "outer" "output" "pad" "parameter" "parameters"
1488"partial" "path" "postfix" "prefix" "preorder" "prepare" "preserve"
1489"primary" "prior" "privileges" "procedure" "public" "read" "reads"
1490"recursive" "references" "referencing" "relative" "restrict" "result"
1491"return" "returns" "revoke" "right" "role" "rollback" "rollup"
1492"routine" "rows" "savepoint" "schema" "scroll" "search" "second"
1493"section" "select" "sequence" "session" "set" "sets" "size" "some"
1494"space" "specific" "specifictype" "sql" "sqlexception" "sqlstate"
1495"sqlwarning" "start" "state" "statement" "static" "structure" "table"
1496"temporary" "terminate" "than" "then" "timezone_hour"
1497"timezone_minute" "to" "trailing" "transaction" "translation"
1498"trigger" "true" "under" "union" "unique" "unknown" "unnest" "update"
1499"usage" "using" "value" "values" "variable" "view" "when" "whenever"
1500"where" "with" "without" "work" "write" "year"
7492acc9 1501)
9fd8cb36 1502
7492acc9
MM
1503 ;; ANSI Functions
1504 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
1505"abs" "avg" "bit_length" "cardinality" "cast" "char_length"
1506"character_length" "coalesce" "convert" "count" "current_date"
1507"current_path" "current_role" "current_time" "current_timestamp"
1508"current_user" "extract" "localtime" "localtimestamp" "lower" "max"
1509"min" "mod" "nullif" "octet_length" "overlay" "placing" "session_user"
1510"substring" "sum" "system_user" "translate" "treat" "trim" "upper"
1511"user"
1512)
fbcc67e2 1513
7492acc9
MM
1514 ;; ANSI Data Types
1515 (sql-font-lock-keywords-builder 'font-lock-type-face nil
9fd8cb36
SM
1516"array" "binary" "bit" "blob" "boolean" "char" "character" "clob"
1517"date" "dec" "decimal" "double" "float" "int" "integer" "interval"
1518"large" "national" "nchar" "nclob" "numeric" "object" "precision"
1519"real" "ref" "row" "scope" "smallint" "time" "timestamp" "varchar"
1520"varying" "zone"
7492acc9 1521))))
95e4b2ef 1522
7492acc9
MM
1523(defvar sql-mode-ansi-font-lock-keywords
1524 (eval-when-compile sql-mode-ansi-font-lock-keywords)
78024f88 1525 "ANSI SQL keywords used by font-lock.
95e4b2ef
RS
1526
1527This variable is used by `sql-mode' and `sql-interactive-mode'. The
1528regular expressions are created during compilation by calling the
1529function `regexp-opt'. Therefore, take a look at the source before
063c6324
JB
1530you define your own `sql-mode-ansi-font-lock-keywords'. You may want
1531to add functions and PL/SQL keywords.")
78024f88 1532
fbcc67e2
MM
1533(defun sql-oracle-show-reserved-words ()
1534 ;; This function is for use by the maintainer of SQL.EL only.
1535 (interactive)
1536 (if (or (and (not (derived-mode-p 'sql-mode))
1537 (not (derived-mode-p 'sql-interactive-mode)))
1538 (not sql-buffer)
1539 (not (eq sql-product 'oracle)))
1540 (error "Not an Oracle buffer")
1541
1542 (let ((b "*RESERVED WORDS*"))
1543 (sql-execute sql-buffer b
1544 (concat "SELECT "
1545 " keyword "
1546 ", reserved AS \"Res\" "
1547 ", res_type AS \"Type\" "
1548 ", res_attr AS \"Attr\" "
1549 ", res_semi AS \"Semi\" "
1550 ", duplicate AS \"Dup\" "
1551 "FROM V$RESERVED_WORDS "
1552 "WHERE length > 1 "
1553 "AND SUBSTR(keyword, 1, 1) BETWEEN 'A' AND 'Z' "
1554 "ORDER BY 2 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC, 1;")
1555 nil nil)
1556 (with-current-buffer b
1557 (set (make-local-variable 'sql-product) 'oracle)
1558 (sql-product-font-lock t nil)
1559 (font-lock-mode +1)))))
1560
78024f88 1561(defvar sql-mode-oracle-font-lock-keywords
7492acc9
MM
1562 (eval-when-compile
1563 (list
1564 ;; Oracle SQL*Plus Commands
fbcc67e2
MM
1565 ;; Only recognized in they start in column 1 and the
1566 ;; abbreviation is followed by a space or the end of line.
7492acc9 1567
fbcc67e2
MM
1568 "\\|"
1569 (list (concat "^" (sql-regexp-abbrev "rem~ark") "\\(?:\\s-.*\\)?$")
1570 0 'font-lock-comment-face t)
1571
1572 (list
1573 (concat
1574 "^\\(?:"
1575 (sql-regexp-abbrev-list
1576 "[@]\\{1,2\\}" "acc~ept" "a~ppend" "archive" "attribute"
1577 "bre~ak" "bti~tle" "c~hange" "cl~ear" "col~umn" "conn~ect"
1578 "copy" "def~ine" "del" "desc~ribe" "disc~onnect" "ed~it"
1579 "exec~ute" "exit" "get" "help" "ho~st" "[$]" "i~nput" "l~ist"
1580 "passw~ord" "pau~se" "pri~nt" "pro~mpt" "quit" "recover"
1581 "repf~ooter" "reph~eader" "r~un" "sav~e" "sho~w" "shutdown"
1582 "spo~ol" "sta~rt" "startup" "store" "tim~ing" "tti~tle"
1583 "undef~ine" "var~iable" "whenever")
1584 "\\|"
1585 (concat "\\(?:"
1586 (sql-regexp-abbrev "comp~ute")
1587 "\\s-+"
1588 (sql-regexp-abbrev-list
1589 "avg" "cou~nt" "min~imum" "max~imum" "num~ber" "sum"
1590 "std" "var~iance")
1591 "\\)")
1592 "\\|"
1593 (concat "\\(?:set\\s-+"
1594 (sql-regexp-abbrev-list
1595 "appi~nfo" "array~size" "auto~commit" "autop~rint"
1596 "autorecovery" "autot~race" "blo~ckterminator"
1597 "cmds~ep" "colsep" "com~patibility" "con~cat"
1598 "copyc~ommit" "copytypecheck" "def~ine" "describe"
1599 "echo" "editf~ile" "emb~edded" "esc~ape" "feed~back"
1600 "flagger" "flu~sh" "hea~ding" "heads~ep" "instance"
1601 "lin~esize" "lobof~fset" "long" "longc~hunksize"
1602 "mark~up" "newp~age" "null" "numf~ormat" "num~width"
1603 "pages~ize" "pau~se" "recsep" "recsepchar"
1604 "scan" "serverout~put" "shift~inout" "show~mode"
1605 "sqlbl~anklines" "sqlc~ase" "sqlco~ntinue"
1606 "sqln~umber" "sqlpluscompat~ibility" "sqlpre~fix"
1607 "sqlp~rompt" "sqlt~erminator" "suf~fix" "tab"
1608 "term~out" "ti~me" "timi~ng" "trim~out" "trims~pool"
1609 "und~erline" "ver~ify" "wra~p")
1610 "\\)")
1611
1612 "\\)\\(?:\\s-.*\\)?\\(?:[-]\n.*\\)*$")
1613 0 'font-lock-doc-face t)
7492acc9
MM
1614
1615 ;; Oracle Functions
1616 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
fbcc67e2
MM
1617"abs" "acos" "add_months" "appendchildxml" "ascii" "asciistr" "asin"
1618"atan" "atan2" "avg" "bfilename" "bin_to_num" "bitand" "cardinality"
1619"cast" "ceil" "chartorowid" "chr" "cluster_id" "cluster_probability"
1620"cluster_set" "coalesce" "collect" "compose" "concat" "convert" "corr"
bb5aa5d6 1621"connect_by_root" "connect_by_iscycle" "connect_by_isleaf"
fbcc67e2 1622"corr_k" "corr_s" "cos" "cosh" "count" "covar_pop" "covar_samp"
c7015153 1623"cube_table" "cume_dist" "current_date" "current_timestamp" "cv"
fbcc67e2
MM
1624"dataobj_to_partition" "dbtimezone" "decode" "decompose" "deletexml"
1625"dense_rank" "depth" "deref" "dump" "empty_blob" "empty_clob"
1626"existsnode" "exp" "extract" "extractvalue" "feature_id" "feature_set"
1627"feature_value" "first" "first_value" "floor" "from_tz" "greatest"
1628"grouping" "grouping_id" "group_id" "hextoraw" "initcap"
1629"insertchildxml" "insertchildxmlafter" "insertchildxmlbefore"
1630"insertxmlafter" "insertxmlbefore" "instr" "instr2" "instr4" "instrb"
1631"instrc" "iteration_number" "lag" "last" "last_day" "last_value"
1632"lead" "least" "length" "length2" "length4" "lengthb" "lengthc"
1633"listagg" "ln" "lnnvl" "localtimestamp" "log" "lower" "lpad" "ltrim"
1634"make_ref" "max" "median" "min" "mod" "months_between" "nanvl" "nchr"
1635"new_time" "next_day" "nlssort" "nls_charset_decl_len"
9fd8cb36 1636"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower"
fbcc67e2
MM
1637"nls_upper" "nth_value" "ntile" "nullif" "numtodsinterval"
1638"numtoyminterval" "nvl" "nvl2" "ora_dst_affected" "ora_dst_convert"
1639"ora_dst_error" "ora_hash" "path" "percentile_cont" "percentile_disc"
1640"percent_rank" "power" "powermultiset" "powermultiset_by_cardinality"
1641"prediction" "prediction_bounds" "prediction_cost"
1642"prediction_details" "prediction_probability" "prediction_set"
1643"presentnnv" "presentv" "previous" "rank" "ratio_to_report" "rawtohex"
1644"rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr"
1645"regexp_replace" "regexp_substr" "regr_avgx" "regr_avgy" "regr_count"
1646"regr_intercept" "regr_r2" "regr_slope" "regr_sxx" "regr_sxy"
1647"regr_syy" "remainder" "replace" "round" "rowidtochar" "rowidtonchar"
1648"row_number" "rpad" "rtrim" "scn_to_timestamp" "sessiontimezone" "set"
1649"sign" "sin" "sinh" "soundex" "sqrt" "stats_binomial_test"
1650"stats_crosstab" "stats_f_test" "stats_ks_test" "stats_mode"
1651"stats_mw_test" "stats_one_way_anova" "stats_t_test_indep"
1652"stats_t_test_indepu" "stats_t_test_one" "stats_t_test_paired"
1653"stats_wsr_test" "stddev" "stddev_pop" "stddev_samp" "substr"
1654"substr2" "substr4" "substrb" "substrc" "sum" "sysdate" "systimestamp"
1655"sys_connect_by_path" "sys_context" "sys_dburigen" "sys_extract_utc"
1656"sys_guid" "sys_typeid" "sys_xmlagg" "sys_xmlgen" "tan" "tanh"
1657"timestamp_to_scn" "to_binary_double" "to_binary_float" "to_blob"
9fd8cb36
SM
1658"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
1659"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
1660"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
fbcc67e2
MM
1661"tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv"
1662"value" "variance" "var_pop" "var_samp" "vsize" "width_bucket"
1663"xmlagg" "xmlcast" "xmlcdata" "xmlcolattval" "xmlcomment" "xmlconcat"
1664"xmldiff" "xmlelement" "xmlexists" "xmlforest" "xmlisvalid" "xmlparse"
1665"xmlpatch" "xmlpi" "xmlquery" "xmlroot" "xmlsequence" "xmlserialize"
1666"xmltable" "xmltransform"
7492acc9 1667)
fbcc67e2
MM
1668
1669 ;; See the table V$RESERVED_WORDS
7492acc9
MM
1670 ;; Oracle Keywords
1671 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
9fd8cb36
SM
1672"abort" "access" "accessed" "account" "activate" "add" "admin"
1673"advise" "after" "agent" "aggregate" "all" "allocate" "allow" "alter"
1674"always" "analyze" "ancillary" "and" "any" "apply" "archive"
1675"archivelog" "array" "as" "asc" "associate" "at" "attribute"
1676"attributes" "audit" "authenticated" "authid" "authorization" "auto"
1677"autoallocate" "automatic" "availability" "backup" "before" "begin"
1678"behalf" "between" "binding" "bitmap" "block" "blocksize" "body"
1679"both" "buffer_pool" "build" "by" "cache" "call" "cancel"
1680"cascade" "case" "category" "certificate" "chained" "change" "check"
1681"checkpoint" "child" "chunk" "class" "clear" "clone" "close" "cluster"
1682"column" "column_value" "columns" "comment" "commit" "committed"
1683"compatibility" "compile" "complete" "composite_limit" "compress"
1684"compute" "connect" "connect_time" "consider" "consistent"
1685"constraint" "constraints" "constructor" "contents" "context"
1686"continue" "controlfile" "corruption" "cost" "cpu_per_call"
1687"cpu_per_session" "create" "cross" "cube" "current" "currval" "cycle"
1688"dangling" "data" "database" "datafile" "datafiles" "day" "ddl"
1689"deallocate" "debug" "default" "deferrable" "deferred" "definer"
1690"delay" "delete" "demand" "desc" "determines" "deterministic"
1691"dictionary" "dimension" "directory" "disable" "disassociate"
1692"disconnect" "distinct" "distinguished" "distributed" "dml" "drop"
1693"each" "element" "else" "enable" "end" "equals_path" "escape"
1694"estimate" "except" "exceptions" "exchange" "excluding" "exists"
1695"expire" "explain" "extent" "external" "externally"
1696"failed_login_attempts" "fast" "file" "final" "finish" "flush" "for"
1697"force" "foreign" "freelist" "freelists" "freepools" "fresh" "from"
1698"full" "function" "functions" "generated" "global" "global_name"
1699"globally" "grant" "group" "grouping" "groups" "guard" "hash"
1700"hashkeys" "having" "heap" "hierarchy" "id" "identified" "identifier"
1701"idle_time" "immediate" "in" "including" "increment" "index" "indexed"
1702"indexes" "indextype" "indextypes" "indicator" "initial" "initialized"
1703"initially" "initrans" "inner" "insert" "instance" "instantiable"
1704"instead" "intersect" "into" "invalidate" "is" "isolation" "java"
1705"join" "keep" "key" "kill" "language" "left" "less" "level"
1706"levels" "library" "like" "like2" "like4" "likec" "limit" "link"
1707"list" "lob" "local" "location" "locator" "lock" "log" "logfile"
1708"logging" "logical" "logical_reads_per_call"
1709"logical_reads_per_session" "managed" "management" "manual" "map"
1710"mapping" "master" "matched" "materialized" "maxdatafiles"
1711"maxextents" "maximize" "maxinstances" "maxlogfiles" "maxloghistory"
1712"maxlogmembers" "maxsize" "maxtrans" "maxvalue" "member" "memory"
1713"merge" "migrate" "minextents" "minimize" "minimum" "minus" "minvalue"
1714"mode" "modify" "monitoring" "month" "mount" "move" "movement" "name"
1715"named" "natural" "nested" "never" "new" "next" "nextval" "no"
1716"noarchivelog" "noaudit" "nocache" "nocompress" "nocopy" "nocycle"
1717"nodelay" "noforce" "nologging" "nomapping" "nomaxvalue" "nominimize"
1718"nominvalue" "nomonitoring" "none" "noorder" "noparallel" "norely"
1719"noresetlogs" "noreverse" "normal" "norowdependencies" "nosort"
1720"noswitch" "not" "nothing" "notimeout" "novalidate" "nowait" "null"
1721"nulls" "object" "of" "off" "offline" "oidindex" "old" "on" "online"
1722"only" "open" "operator" "optimal" "option" "or" "order"
1723"organization" "out" "outer" "outline" "overflow" "overriding"
1724"package" "packages" "parallel" "parallel_enable" "parameters"
1725"parent" "partition" "partitions" "password" "password_grace_time"
1726"password_life_time" "password_lock_time" "password_reuse_max"
1727"password_reuse_time" "password_verify_function" "pctfree"
1728"pctincrease" "pctthreshold" "pctused" "pctversion" "percent"
1729"performance" "permanent" "pfile" "physical" "pipelined" "plan"
1730"post_transaction" "pragma" "prebuilt" "preserve" "primary" "private"
1731"private_sga" "privileges" "procedure" "profile" "protection" "public"
1732"purge" "query" "quiesce" "quota" "range" "read" "reads" "rebuild"
1733"records_per_block" "recover" "recovery" "recycle" "reduced" "ref"
1734"references" "referencing" "refresh" "register" "reject" "relational"
1735"rely" "rename" "reset" "resetlogs" "resize" "resolve" "resolver"
1736"resource" "restrict" "restrict_references" "restricted" "result"
1737"resumable" "resume" "retention" "return" "returning" "reuse"
1738"reverse" "revoke" "rewrite" "right" "rnds" "rnps" "role" "roles"
1739"rollback" "rollup" "row" "rowdependencies" "rownum" "rows" "sample"
1740"savepoint" "scan" "schema" "scn" "scope" "segment" "select"
1741"selectivity" "self" "sequence" "serializable" "session"
1742"sessions_per_user" "set" "sets" "settings" "shared" "shared_pool"
1743"shrink" "shutdown" "siblings" "sid" "single" "size" "skip" "some"
1744"sort" "source" "space" "specification" "spfile" "split" "standby"
1745"start" "statement_id" "static" "statistics" "stop" "storage" "store"
1746"structure" "subpartition" "subpartitions" "substitutable"
1747"successful" "supplemental" "suspend" "switch" "switchover" "synonym"
1748"sys" "system" "table" "tables" "tablespace" "tempfile" "template"
1749"temporary" "test" "than" "then" "thread" "through" "time_zone"
1750"timeout" "to" "trace" "transaction" "trigger" "triggers" "truncate"
1751"trust" "type" "types" "unarchived" "under" "under_path" "undo"
1752"uniform" "union" "unique" "unlimited" "unlock" "unquiesce"
1753"unrecoverable" "until" "unusable" "unused" "update" "upgrade" "usage"
1754"use" "using" "validate" "validation" "value" "values" "variable"
1755"varray" "version" "view" "wait" "when" "whenever" "where" "with"
1756"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype"
7492acc9 1757)
fbcc67e2 1758
7492acc9
MM
1759 ;; Oracle Data Types
1760 (sql-font-lock-keywords-builder 'font-lock-type-face nil
fbcc67e2
MM
1761"bfile" "binary_double" "binary_float" "blob" "byte" "char" "charbyte"
1762"clob" "date" "day" "float" "interval" "local" "long" "longraw"
1763"minute" "month" "nchar" "nclob" "number" "nvarchar2" "raw" "rowid" "second"
1764"time" "timestamp" "urowid" "varchar2" "with" "year" "zone"
7492acc9 1765)
9fd8cb36 1766
7492acc9 1767 ;; Oracle PL/SQL Attributes
fbcc67e2
MM
1768 (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b")
1769"bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound"
1770"rowcount" "rowtype" "type"
7492acc9
MM
1771)
1772
1773 ;; Oracle PL/SQL Functions
1774 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
fbcc67e2
MM
1775"delete" "trim" "extend" "exists" "first" "last" "count" "limit"
1776"prior" "next"
1777)
1778
1779 ;; Oracle PL/SQL Reserved words
1780 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1781"all" "alter" "and" "any" "as" "asc" "at" "begin" "between" "by"
1782"case" "check" "clusters" "cluster" "colauth" "columns" "compress"
1783"connect" "crash" "create" "cursor" "declare" "default" "desc"
1784"distinct" "drop" "else" "end" "exception" "exclusive" "fetch" "for"
1785"from" "function" "goto" "grant" "group" "having" "identified" "if"
1786"in" "index" "indexes" "insert" "intersect" "into" "is" "like" "lock"
1787"minus" "mode" "nocompress" "not" "nowait" "null" "of" "on" "option"
1788"or" "order" "overlaps" "procedure" "public" "resource" "revoke"
1789"select" "share" "size" "sql" "start" "subtype" "tabauth" "table"
1790"then" "to" "type" "union" "unique" "update" "values" "view" "views"
1791"when" "where" "with"
1792
1793"true" "false"
1794"raise_application_error"
7492acc9 1795)
9fd8cb36 1796
7492acc9
MM
1797 ;; Oracle PL/SQL Keywords
1798 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
fbcc67e2
MM
1799"a" "add" "agent" "aggregate" "array" "attribute" "authid" "avg"
1800"bfile_base" "binary" "blob_base" "block" "body" "both" "bound" "bulk"
1801"byte" "c" "call" "calling" "cascade" "char" "char_base" "character"
1802"charset" "charsetform" "charsetid" "clob_base" "close" "collect"
1803"comment" "commit" "committed" "compiled" "constant" "constructor"
1804"context" "continue" "convert" "count" "current" "customdatum"
1805"dangling" "data" "date" "date_base" "day" "define" "delete"
1806"deterministic" "double" "duration" "element" "elsif" "empty" "escape"
1807"except" "exceptions" "execute" "exists" "exit" "external" "final"
1808"fixed" "float" "forall" "force" "general" "hash" "heap" "hidden"
1809"hour" "immediate" "including" "indicator" "indices" "infinite"
1810"instantiable" "int" "interface" "interval" "invalidate" "isolation"
1811"java" "language" "large" "leading" "length" "level" "library" "like2"
1812"like4" "likec" "limit" "limited" "local" "long" "loop" "map" "max"
1813"maxlen" "member" "merge" "min" "minute" "mod" "modify" "month"
1814"multiset" "name" "nan" "national" "native" "nchar" "new" "nocopy"
1815"number_base" "object" "ocicoll" "ocidate" "ocidatetime" "ociduration"
1816"ociinterval" "ociloblocator" "ocinumber" "ociraw" "ociref"
1817"ocirefcursor" "ocirowid" "ocistring" "ocitype" "old" "only" "opaque"
1818"open" "operator" "oracle" "oradata" "organization" "orlany" "orlvary"
1819"others" "out" "overriding" "package" "parallel_enable" "parameter"
1820"parameters" "parent" "partition" "pascal" "pipe" "pipelined" "pragma"
1821"precision" "prior" "private" "raise" "range" "raw" "read" "record"
1822"ref" "reference" "relies_on" "rem" "remainder" "rename" "result"
1823"result_cache" "return" "returning" "reverse" "rollback" "row"
1824"sample" "save" "savepoint" "sb1" "sb2" "sb4" "second" "segment"
1825"self" "separate" "sequence" "serializable" "set" "short" "size_t"
1826"some" "sparse" "sqlcode" "sqldata" "sqlname" "sqlstate" "standard"
1827"static" "stddev" "stored" "string" "struct" "style" "submultiset"
1828"subpartition" "substitutable" "sum" "synonym" "tdo" "the" "time"
1829"timestamp" "timezone_abbr" "timezone_hour" "timezone_minute"
1830"timezone_region" "trailing" "transaction" "transactional" "trusted"
1831"ub1" "ub2" "ub4" "under" "unsigned" "untrusted" "use" "using"
1832"valist" "value" "variable" "variance" "varray" "varying" "void"
1833"while" "work" "wrapped" "write" "year" "zone"
1834;; Pragma
1835"autonomous_transaction" "exception_init" "inline"
1836"restrict_references" "serially_reusable"
7492acc9 1837)
9fd8cb36 1838
7492acc9
MM
1839 ;; Oracle PL/SQL Data Types
1840 (sql-font-lock-keywords-builder 'font-lock-type-face nil
fbcc67e2
MM
1841"\"BINARY LARGE OBJECT\"" "\"CHAR LARGE OBJECT\"" "\"CHAR VARYING\""
1842"\"CHARACTER LARGE OBJECT\"" "\"CHARACTER VARYING\""
1843"\"DOUBLE PRECISION\"" "\"INTERVAL DAY TO SECOND\""
1844"\"INTERVAL YEAR TO MONTH\"" "\"LONG RAW\"" "\"NATIONAL CHAR\""
1845"\"NATIONAL CHARACTER LARGE OBJECT\"" "\"NATIONAL CHARACTER\""
1846"\"NCHAR LARGE OBJECT\"" "\"NCHAR\"" "\"NCLOB\"" "\"NVARCHAR2\""
1847"\"TIME WITH TIME ZONE\"" "\"TIMESTAMP WITH LOCAL TIME ZONE\""
1848"\"TIMESTAMP WITH TIME ZONE\""
1849"bfile" "bfile_base" "binary_double" "binary_float" "binary_integer"
1850"blob" "blob_base" "boolean" "char" "character" "char_base" "clob"
1851"clob_base" "cursor" "date" "day" "dec" "decimal"
1852"dsinterval_unconstrained" "float" "int" "integer" "interval" "local"
1853"long" "mlslabel" "month" "natural" "naturaln" "nchar_cs" "number"
1854"number_base" "numeric" "pls_integer" "positive" "positiven" "raw"
1855"real" "ref" "rowid" "second" "signtype" "simple_double"
1856"simple_float" "simple_integer" "smallint" "string" "time" "timestamp"
1857"timestamp_ltz_unconstrained" "timestamp_tz_unconstrained"
1858"timestamp_unconstrained" "time_tz_unconstrained" "time_unconstrained"
1859"to" "urowid" "varchar" "varchar2" "with" "year"
1860"yminterval_unconstrained" "zone"
7492acc9 1861)
9fd8cb36 1862
7492acc9
MM
1863 ;; Oracle PL/SQL Exceptions
1864 (sql-font-lock-keywords-builder 'font-lock-warning-face nil
78024f88
AS
1865"access_into_null" "case_not_found" "collection_is_null"
1866"cursor_already_open" "dup_val_on_index" "invalid_cursor"
fbcc67e2
MM
1867"invalid_number" "login_denied" "no_data_found" "no_data_needed"
1868"not_logged_on" "program_error" "rowtype_mismatch" "self_is_null"
1869"storage_error" "subscript_beyond_count" "subscript_outside_limit"
1870"sys_invalid_rowid" "timeout_on_resource" "too_many_rows"
1871"value_error" "zero_divide"
7492acc9 1872)))
95e4b2ef 1873
78024f88 1874 "Oracle SQL keywords used by font-lock.
95e4b2ef
RS
1875
1876This variable is used by `sql-mode' and `sql-interactive-mode'. The
1877regular expressions are created during compilation by calling the
1878function `regexp-opt'. Therefore, take a look at the source before
063c6324 1879you define your own `sql-mode-oracle-font-lock-keywords'. You may want
78024f88 1880to add functions and PL/SQL keywords.")
95e4b2ef 1881
78024f88 1882(defvar sql-mode-postgres-font-lock-keywords
7492acc9
MM
1883 (eval-when-compile
1884 (list
9250002f
MM
1885 ;; Postgres psql commands
1886 '("^\\s-*\\\\.*$" . font-lock-doc-face)
1887
1888 ;; Postgres unreserved words but may have meaning
1889 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil "a"
1890"abs" "absent" "according" "ada" "alias" "allocate" "are" "array_agg"
1891"asensitive" "atomic" "attribute" "attributes" "avg" "base64"
1892"bernoulli" "bit_length" "bitvar" "blob" "blocked" "bom" "breadth" "c"
1893"call" "cardinality" "catalog_name" "ceil" "ceiling" "char_length"
1894"character_length" "character_set_catalog" "character_set_name"
1895"character_set_schema" "characters" "checked" "class_origin" "clob"
1896"cobol" "collation" "collation_catalog" "collation_name"
1897"collation_schema" "collect" "column_name" "columns"
1898"command_function" "command_function_code" "completion" "condition"
1899"condition_number" "connect" "connection_name" "constraint_catalog"
1900"constraint_name" "constraint_schema" "constructor" "contains"
1901"control" "convert" "corr" "corresponding" "count" "covar_pop"
1902"covar_samp" "cube" "cume_dist" "current_default_transform_group"
1903"current_path" "current_transform_group_for_type" "cursor_name"
1904"datalink" "datetime_interval_code" "datetime_interval_precision" "db"
1905"defined" "degree" "dense_rank" "depth" "deref" "derived" "describe"
1906"descriptor" "destroy" "destructor" "deterministic" "diagnostics"
1907"disconnect" "dispatch" "dlnewcopy" "dlpreviouscopy" "dlurlcomplete"
1908"dlurlcompleteonly" "dlurlcompletewrite" "dlurlpath" "dlurlpathonly"
1909"dlurlpathwrite" "dlurlscheme" "dlurlserver" "dlvalue" "dynamic"
1910"dynamic_function" "dynamic_function_code" "element" "empty"
1911"end-exec" "equals" "every" "exception" "exec" "existing" "exp" "file"
1912"filter" "final" "first_value" "flag" "floor" "fortran" "found" "free"
1913"fs" "fusion" "g" "general" "generated" "get" "go" "goto" "grouping"
1914"hex" "hierarchy" "host" "id" "ignore" "implementation" "import"
1915"indent" "indicator" "infix" "initialize" "instance" "instantiable"
1916"integrity" "intersection" "iterate" "k" "key_member" "key_type" "lag"
1917"last_value" "lateral" "lead" "length" "less" "library" "like_regex"
1918"link" "ln" "locator" "lower" "m" "map" "matched" "max"
1919"max_cardinality" "member" "merge" "message_length"
1920"message_octet_length" "message_text" "method" "min" "mod" "modifies"
1921"modify" "module" "more" "multiset" "mumps" "namespace" "nclob"
1922"nesting" "new" "nfc" "nfd" "nfkc" "nfkd" "nil" "normalize"
1923"normalized" "nth_value" "ntile" "nullable" "number"
1924"occurrences_regex" "octet_length" "octets" "old" "open" "operation"
1925"ordering" "ordinality" "others" "output" "overriding" "p" "pad"
1926"parameter" "parameter_mode" "parameter_name"
1927"parameter_ordinal_position" "parameter_specific_catalog"
1928"parameter_specific_name" "parameter_specific_schema" "parameters"
1929"pascal" "passing" "passthrough" "percent_rank" "percentile_cont"
1930"percentile_disc" "permission" "pli" "position_regex" "postfix"
1931"power" "prefix" "preorder" "public" "rank" "reads" "recovery" "ref"
1932"referencing" "regr_avgx" "regr_avgy" "regr_count" "regr_intercept"
1933"regr_r2" "regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "requiring"
1934"respect" "restore" "result" "return" "returned_cardinality"
1935"returned_length" "returned_octet_length" "returned_sqlstate" "rollup"
1936"routine" "routine_catalog" "routine_name" "routine_schema"
1937"row_count" "row_number" "scale" "schema_name" "scope" "scope_catalog"
1938"scope_name" "scope_schema" "section" "selective" "self" "sensitive"
1939"server_name" "sets" "size" "source" "space" "specific"
1940"specific_name" "specifictype" "sql" "sqlcode" "sqlerror"
1941"sqlexception" "sqlstate" "sqlwarning" "sqrt" "state" "static"
1942"stddev_pop" "stddev_samp" "structure" "style" "subclass_origin"
1943"sublist" "submultiset" "substring_regex" "sum" "system_user" "t"
1944"table_name" "tablesample" "terminate" "than" "ties" "timezone_hour"
1945"timezone_minute" "token" "top_level_count" "transaction_active"
1946"transactions_committed" "transactions_rolled_back" "transform"
1947"transforms" "translate" "translate_regex" "translation"
1948"trigger_catalog" "trigger_name" "trigger_schema" "trim_array"
1949"uescape" "under" "unlink" "unnamed" "unnest" "untyped" "upper" "uri"
1950"usage" "user_defined_type_catalog" "user_defined_type_code"
1951"user_defined_type_name" "user_defined_type_schema" "var_pop"
1952"var_samp" "varbinary" "variable" "whenever" "width_bucket" "within"
1953"xmlagg" "xmlbinary" "xmlcast" "xmlcomment" "xmldeclaration"
1954"xmldocument" "xmlexists" "xmliterate" "xmlnamespaces" "xmlquery"
1955"xmlschema" "xmltable" "xmltext" "xmlvalidate"
1956)
1957
1958 ;; Postgres non-reserved words
7492acc9 1959 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
9250002f
MM
1960"abort" "absolute" "access" "action" "add" "admin" "after" "aggregate"
1961"also" "alter" "always" "assertion" "assignment" "at" "backward"
1962"before" "begin" "between" "by" "cache" "called" "cascade" "cascaded"
1963"catalog" "chain" "characteristics" "checkpoint" "class" "close"
1964"cluster" "coalesce" "comment" "comments" "commit" "committed"
1965"configuration" "connection" "constraints" "content" "continue"
1966"conversion" "copy" "cost" "createdb" "createrole" "createuser" "csv"
1967"current" "cursor" "cycle" "data" "database" "day" "deallocate" "dec"
1968"declare" "defaults" "deferred" "definer" "delete" "delimiter"
1969"delimiters" "dictionary" "disable" "discard" "document" "domain"
1970"drop" "each" "enable" "encoding" "encrypted" "enum" "escape"
1971"exclude" "excluding" "exclusive" "execute" "exists" "explain"
1972"external" "extract" "family" "first" "float" "following" "force"
1973"forward" "function" "functions" "global" "granted" "greatest"
1974"handler" "header" "hold" "hour" "identity" "if" "immediate"
1975"immutable" "implicit" "including" "increment" "index" "indexes"
1976"inherit" "inherits" "inline" "inout" "input" "insensitive" "insert"
1977"instead" "invoker" "isolation" "key" "language" "large" "last"
1978"lc_collate" "lc_ctype" "least" "level" "listen" "load" "local"
1979"location" "lock" "login" "mapping" "match" "maxvalue" "minute"
1980"minvalue" "mode" "month" "move" "name" "names" "national" "nchar"
1981"next" "no" "nocreatedb" "nocreaterole" "nocreateuser" "noinherit"
1982"nologin" "none" "nosuperuser" "nothing" "notify" "nowait" "nullif"
1983"nulls" "object" "of" "oids" "operator" "option" "options" "out"
1984"overlay" "owned" "owner" "parser" "partial" "partition" "password"
1985"plans" "position" "preceding" "prepare" "prepared" "preserve" "prior"
1986"privileges" "procedural" "procedure" "quote" "range" "read"
1987"reassign" "recheck" "recursive" "reindex" "relative" "release"
1988"rename" "repeatable" "replace" "replica" "reset" "restart" "restrict"
1989"returns" "revoke" "role" "rollback" "row" "rows" "rule" "savepoint"
1990"schema" "scroll" "search" "second" "security" "sequence" "sequences"
1991"serializable" "server" "session" "set" "setof" "share" "show"
1992"simple" "stable" "standalone" "start" "statement" "statistics"
1993"stdin" "stdout" "storage" "strict" "strip" "substring" "superuser"
1994"sysid" "system" "tables" "tablespace" "temp" "template" "temporary"
1995"transaction" "treat" "trigger" "trim" "truncate" "trusted" "type"
1996"unbounded" "uncommitted" "unencrypted" "unknown" "unlisten" "until"
1997"update" "vacuum" "valid" "validator" "value" "values" "version"
1998"view" "volatile" "whitespace" "work" "wrapper" "write"
1999"xmlattributes" "xmlconcat" "xmlelement" "xmlforest" "xmlparse"
2000"xmlpi" "xmlroot" "xmlserialize" "year" "yes"
7492acc9 2001)
9250002f 2002
7492acc9
MM
2003 ;; Postgres Reserved
2004 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
9250002f
MM
2005"all" "analyse" "analyze" "and" "any" "array" "asc" "as" "asymmetric"
2006"authorization" "binary" "both" "case" "cast" "check" "collate"
2007"column" "concurrently" "constraint" "create" "cross"
2008"current_catalog" "current_date" "current_role" "current_schema"
2009"current_time" "current_timestamp" "current_user" "default"
2010"deferrable" "desc" "distinct" "do" "else" "end" "except" "false"
2011"fetch" "foreign" "for" "freeze" "from" "full" "grant" "group"
2012"having" "ilike" "initially" "inner" "in" "intersect" "into" "isnull"
2013"is" "join" "leading" "left" "like" "limit" "localtime"
2014"localtimestamp" "natural" "notnull" "not" "null" "off" "offset"
2015"only" "on" "order" "or" "outer" "overlaps" "over" "placing" "primary"
2016"references" "returning" "right" "select" "session_user" "similar"
2017"some" "symmetric" "table" "then" "to" "trailing" "true" "union"
2018"unique" "user" "using" "variadic" "verbose" "when" "where" "window"
2019"with"
7492acc9 2020)
9fd8cb36 2021
7492acc9
MM
2022 ;; Postgres Data Types
2023 (sql-font-lock-keywords-builder 'font-lock-type-face nil
9250002f
MM
2024"bigint" "bigserial" "bit" "bool" "boolean" "box" "bytea" "char"
2025"character" "cidr" "circle" "date" "decimal" "double" "float4"
2026"float8" "inet" "int" "int2" "int4" "int8" "integer" "interval" "line"
2027"lseg" "macaddr" "money" "numeric" "path" "point" "polygon"
2028"precision" "real" "serial" "serial4" "serial8" "smallint" "text"
2029"time" "timestamp" "timestamptz" "timetz" "tsquery" "tsvector"
2030"txid_snapshot" "uuid" "varbit" "varchar" "varying" "without"
2031"xml" "zone"
9fd8cb36
SM
2032)))
2033
78024f88 2034 "Postgres SQL keywords used by font-lock.
f4df536d
JB
2035
2036This variable is used by `sql-mode' and `sql-interactive-mode'. The
2037regular expressions are created during compilation by calling the
78024f88 2038function `regexp-opt'. Therefore, take a look at the source before
063c6324 2039you define your own `sql-mode-postgres-font-lock-keywords'.")
f4df536d 2040
78024f88 2041(defvar sql-mode-linter-font-lock-keywords
7492acc9
MM
2042 (eval-when-compile
2043 (list
2044 ;; Linter Keywords
2045 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
f4df536d
JB
2046"autocommit" "autoinc" "autorowid" "cancel" "cascade" "channel"
2047"committed" "count" "countblob" "cross" "current" "data" "database"
2048"datafile" "datafiles" "datesplit" "dba" "dbname" "default" "deferred"
2049"denied" "description" "device" "difference" "directory" "error"
2050"escape" "euc" "exclusive" "external" "extfile" "false" "file"
2051"filename" "filesize" "filetime" "filter" "findblob" "first" "foreign"
2052"full" "fuzzy" "global" "granted" "ignore" "immediate" "increment"
2053"indexes" "indexfile" "indexfiles" "indextime" "initial" "integrity"
2054"internal" "key" "last_autoinc" "last_rowid" "limit" "linter"
2055"linter_file_device" "linter_file_size" "linter_name_length" "ln"
2056"local" "login" "maxisn" "maxrow" "maxrowid" "maxvalue" "message"
2057"minvalue" "module" "names" "national" "natural" "new" "new_table"
2058"no" "node" "noneuc" "nulliferror" "numbers" "off" "old" "old_table"
2059"only" "operation" "optimistic" "option" "page" "partially" "password"
2060"phrase" "plan" "precision" "primary" "priority" "privileges"
2061"proc_info_size" "proc_par_name_len" "protocol" "quant" "range" "raw"
2062"read" "record" "records" "references" "remote" "rename" "replication"
2063"restart" "rewrite" "root" "row" "rule" "savepoint" "security"
2064"sensitive" "sequence" "serializable" "server" "since" "size" "some"
2065"startup" "statement" "station" "success" "sys_guid" "tables" "test"
2066"timeout" "trace" "transaction" "translation" "trigger"
2067"trigger_info_size" "true" "trunc" "uncommitted" "unicode" "unknown"
2068"unlimited" "unlisted" "user" "utf8" "value" "varying" "volumes"
2069"wait" "windows_code" "workspace" "write" "xml"
7492acc9 2070)
78024f88 2071
7492acc9
MM
2072 ;; Linter Reserved
2073 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
f4df536d
JB
2074"access" "action" "add" "address" "after" "all" "alter" "always" "and"
2075"any" "append" "as" "asc" "ascic" "async" "at_begin" "at_end" "audit"
2076"aud_obj_name_len" "backup" "base" "before" "between" "blobfile"
2077"blobfiles" "blobpct" "brief" "browse" "by" "case" "cast" "check"
2078"clear" "close" "column" "comment" "commit" "connect" "contains"
2079"correct" "create" "delete" "desc" "disable" "disconnect" "distinct"
2080"drop" "each" "ef" "else" "enable" "end" "event" "except" "exclude"
2081"execute" "exists" "extract" "fetch" "finish" "for" "from" "get"
2082"grant" "group" "having" "identified" "in" "index" "inner" "insert"
2083"instead" "intersect" "into" "is" "isolation" "join" "left" "level"
2084"like" "lock" "mode" "modify" "not" "nowait" "null" "of" "on" "open"
2085"or" "order" "outer" "owner" "press" "prior" "procedure" "public"
2086"purge" "rebuild" "resource" "restrict" "revoke" "right" "role"
2087"rollback" "rownum" "select" "session" "set" "share" "shutdown"
2088"start" "stop" "sync" "synchronize" "synonym" "sysdate" "table" "then"
2089"to" "union" "unique" "unlock" "until" "update" "using" "values"
2090"view" "when" "where" "with" "without"
7492acc9 2091)
78024f88 2092
7492acc9
MM
2093 ;; Linter Functions
2094 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
f4df536d
JB
2095"abs" "acos" "asin" "atan" "atan2" "avg" "ceil" "cos" "cosh" "divtime"
2096"exp" "floor" "getbits" "getblob" "getbyte" "getlong" "getraw"
2097"getstr" "gettext" "getword" "hextoraw" "lenblob" "length" "log"
2098"lower" "lpad" "ltrim" "max" "min" "mod" "monthname" "nvl"
2099"octet_length" "power" "rand" "rawtohex" "repeat_string"
2100"right_substr" "round" "rpad" "rtrim" "sign" "sin" "sinh" "soundex"
2101"sqrt" "sum" "tan" "tanh" "timeint_to_days" "to_char" "to_date"
2102"to_gmtime" "to_localtime" "to_number" "trim" "upper" "decode"
2103"substr" "substring" "chr" "dayname" "days" "greatest" "hex" "initcap"
2104"instr" "least" "multime" "replace" "width"
7492acc9 2105)
78024f88 2106
7492acc9
MM
2107 ;; Linter Data Types
2108 (sql-font-lock-keywords-builder 'font-lock-type-face nil
2109"bigint" "bitmap" "blob" "boolean" "char" "character" "date"
2110"datetime" "dec" "decimal" "double" "float" "int" "integer" "nchar"
2111"number" "numeric" "real" "smallint" "varbyte" "varchar" "byte"
2112"cursor" "long"
2113)))
78024f88
AS
2114
2115 "Linter SQL keywords used by font-lock.
f4df536d 2116
78024f88
AS
2117This variable is used by `sql-mode' and `sql-interactive-mode'. The
2118regular expressions are created during compilation by calling the
2119function `regexp-opt'.")
2120
2121(defvar sql-mode-ms-font-lock-keywords
7492acc9
MM
2122 (eval-when-compile
2123 (list
2124 ;; MS isql/osql Commands
2125 (cons
2126 (concat
2127 "^\\(?:\\(?:set\\s-+\\(?:"
2128 (regexp-opt '(
2129"datefirst" "dateformat" "deadlock_priority" "lock_timeout"
2130"concat_null_yields_null" "cursor_close_on_commit"
2131"disable_def_cnst_chk" "fips_flagger" "identity_insert" "language"
2132"offsets" "quoted_identifier" "arithabort" "arithignore" "fmtonly"
2133"nocount" "noexec" "numeric_roundabort" "parseonly"
2134"query_governor_cost_limit" "rowcount" "textsize" "ansi_defaults"
2135"ansi_null_dflt_off" "ansi_null_dflt_on" "ansi_nulls" "ansi_padding"
2136"ansi_warnings" "forceplan" "showplan_all" "showplan_text"
2137"statistics" "implicit_transactions" "remote_proc_transactions"
2138"transaction" "xact_abort"
2139) t)
2140 "\\)\\)\\|go\\s-*\\|use\\s-+\\|setuser\\s-+\\|dbcc\\s-+\\).*$")
2141 'font-lock-doc-face)
2142
2143 ;; MS Reserved
2144 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
78024f88
AS
2145"absolute" "add" "all" "alter" "and" "any" "as" "asc" "authorization"
2146"avg" "backup" "begin" "between" "break" "browse" "bulk" "by"
2147"cascade" "case" "check" "checkpoint" "close" "clustered" "coalesce"
2148"column" "commit" "committed" "compute" "confirm" "constraint"
2149"contains" "containstable" "continue" "controlrow" "convert" "count"
2150"create" "cross" "current" "current_date" "current_time"
9fd8cb36
SM
2151"current_timestamp" "current_user" "database" "deallocate" "declare"
2152"default" "delete" "deny" "desc" "disk" "distinct" "distributed"
2153"double" "drop" "dummy" "dump" "else" "end" "errlvl" "errorexit"
2154"escape" "except" "exec" "execute" "exists" "exit" "fetch" "file"
2155"fillfactor" "first" "floppy" "for" "foreign" "freetext"
78024f88
AS
2156"freetexttable" "from" "full" "goto" "grant" "group" "having"
2157"holdlock" "identity" "identity_insert" "identitycol" "if" "in"
2158"index" "inner" "insert" "intersect" "into" "is" "isolation" "join"
2159"key" "kill" "last" "left" "level" "like" "lineno" "load" "max" "min"
2160"mirrorexit" "national" "next" "nocheck" "nolock" "nonclustered" "not"
2161"null" "nullif" "of" "off" "offsets" "on" "once" "only" "open"
2162"opendatasource" "openquery" "openrowset" "option" "or" "order"
2163"outer" "output" "over" "paglock" "percent" "perm" "permanent" "pipe"
2164"plan" "precision" "prepare" "primary" "print" "prior" "privileges"
2165"proc" "procedure" "processexit" "public" "raiserror" "read"
2166"readcommitted" "readpast" "readtext" "readuncommitted" "reconfigure"
2167"references" "relative" "repeatable" "repeatableread" "replication"
2168"restore" "restrict" "return" "revoke" "right" "rollback" "rowcount"
2169"rowguidcol" "rowlock" "rule" "save" "schema" "select" "serializable"
2170"session_user" "set" "shutdown" "some" "statistics" "sum"
2171"system_user" "table" "tablock" "tablockx" "tape" "temp" "temporary"
2172"textsize" "then" "to" "top" "tran" "transaction" "trigger" "truncate"
2173"tsequal" "uncommitted" "union" "unique" "update" "updatetext"
2174"updlock" "use" "user" "values" "view" "waitfor" "when" "where"
9fd8cb36
SM
2175"while" "with" "work" "writetext" "collate" "function" "openxml"
2176"returns"
7492acc9 2177)
78024f88 2178
7492acc9
MM
2179 ;; MS Functions
2180 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
78024f88
AS
2181"@@connections" "@@cpu_busy" "@@cursor_rows" "@@datefirst" "@@dbts"
2182"@@error" "@@fetch_status" "@@identity" "@@idle" "@@io_busy"
2183"@@langid" "@@language" "@@lock_timeout" "@@max_connections"
2184"@@max_precision" "@@nestlevel" "@@options" "@@pack_received"
2185"@@pack_sent" "@@packet_errors" "@@procid" "@@remserver" "@@rowcount"
2186"@@servername" "@@servicename" "@@spid" "@@textsize" "@@timeticks"
2187"@@total_errors" "@@total_read" "@@total_write" "@@trancount"
2188"@@version" "abs" "acos" "and" "app_name" "ascii" "asin" "atan" "atn2"
2189"avg" "case" "cast" "ceiling" "char" "charindex" "coalesce"
2190"col_length" "col_name" "columnproperty" "containstable" "convert"
2191"cos" "cot" "count" "current_timestamp" "current_user" "cursor_status"
2192"databaseproperty" "datalength" "dateadd" "datediff" "datename"
2193"datepart" "day" "db_id" "db_name" "degrees" "difference" "exp"
2194"file_id" "file_name" "filegroup_id" "filegroup_name"
2195"filegroupproperty" "fileproperty" "floor" "formatmessage"
2196"freetexttable" "fulltextcatalogproperty" "fulltextserviceproperty"
2197"getansinull" "getdate" "grouping" "host_id" "host_name" "ident_incr"
2198"ident_seed" "identity" "index_col" "indexproperty" "is_member"
2199"is_srvrolemember" "isdate" "isnull" "isnumeric" "left" "len" "log"
2200"log10" "lower" "ltrim" "max" "min" "month" "nchar" "newid" "nullif"
2201"object_id" "object_name" "objectproperty" "openquery" "openrowset"
2202"parsename" "patindex" "patindex" "permissions" "pi" "power"
2203"quotename" "radians" "rand" "replace" "replicate" "reverse" "right"
2204"round" "rtrim" "session_user" "sign" "sin" "soundex" "space" "sqrt"
2205"square" "stats_date" "stdev" "stdevp" "str" "stuff" "substring" "sum"
2206"suser_id" "suser_name" "suser_sid" "suser_sname" "system_user" "tan"
2207"textptr" "textvalid" "typeproperty" "unicode" "upper" "user"
2208"user_id" "user_name" "var" "varp" "year"
7492acc9 2209)
78024f88 2210
7492acc9
MM
2211 ;; MS Variables
2212 '("\\b@[a-zA-Z0-9_]*\\b" . font-lock-variable-name-face)
78024f88 2213
7492acc9
MM
2214 ;; MS Types
2215 (sql-font-lock-keywords-builder 'font-lock-type-face nil
2216"binary" "bit" "char" "character" "cursor" "datetime" "dec" "decimal"
2217"double" "float" "image" "int" "integer" "money" "national" "nchar"
2218"ntext" "numeric" "numeric" "nvarchar" "precision" "real"
2219"smalldatetime" "smallint" "smallmoney" "text" "timestamp" "tinyint"
2220"uniqueidentifier" "varbinary" "varchar" "varying"
2221)))
78024f88
AS
2222
2223 "Microsoft SQLServer SQL keywords used by font-lock.
2224
2225This variable is used by `sql-mode' and `sql-interactive-mode'. The
2226regular expressions are created during compilation by calling the
2227function `regexp-opt'. Therefore, take a look at the source before
063c6324 2228you define your own `sql-mode-ms-font-lock-keywords'.")
78024f88 2229
9fd8cb36 2230(defvar sql-mode-sybase-font-lock-keywords nil
78024f88
AS
2231 "Sybase SQL keywords used by font-lock.
2232
2233This variable is used by `sql-mode' and `sql-interactive-mode'. The
2234regular expressions are created during compilation by calling the
2235function `regexp-opt'. Therefore, take a look at the source before
063c6324 2236you define your own `sql-mode-sybase-font-lock-keywords'.")
78024f88 2237
9fd8cb36 2238(defvar sql-mode-informix-font-lock-keywords nil
78024f88
AS
2239 "Informix SQL keywords used by font-lock.
2240
2241This variable is used by `sql-mode' and `sql-interactive-mode'. The
2242regular expressions are created during compilation by calling the
2243function `regexp-opt'. Therefore, take a look at the source before
063c6324 2244you define your own `sql-mode-informix-font-lock-keywords'.")
78024f88 2245
9fd8cb36 2246(defvar sql-mode-interbase-font-lock-keywords nil
78024f88
AS
2247 "Interbase SQL keywords used by font-lock.
2248
2249This variable is used by `sql-mode' and `sql-interactive-mode'. The
2250regular expressions are created during compilation by calling the
2251function `regexp-opt'. Therefore, take a look at the source before
063c6324 2252you define your own `sql-mode-interbase-font-lock-keywords'.")
78024f88 2253
9fd8cb36 2254(defvar sql-mode-ingres-font-lock-keywords nil
78024f88
AS
2255 "Ingres SQL keywords used by font-lock.
2256
2257This variable is used by `sql-mode' and `sql-interactive-mode'. The
2258regular expressions are created during compilation by calling the
2259function `regexp-opt'. Therefore, take a look at the source before
063c6324 2260you define your own `sql-mode-interbase-font-lock-keywords'.")
78024f88 2261
9fd8cb36 2262(defvar sql-mode-solid-font-lock-keywords nil
78024f88
AS
2263 "Solid SQL keywords used by font-lock.
2264
2265This variable is used by `sql-mode' and `sql-interactive-mode'. The
2266regular expressions are created during compilation by calling the
2267function `regexp-opt'. Therefore, take a look at the source before
063c6324 2268you define your own `sql-mode-solid-font-lock-keywords'.")
78024f88 2269
9fd8cb36 2270(defvar sql-mode-mysql-font-lock-keywords
7492acc9
MM
2271 (eval-when-compile
2272 (list
2273 ;; MySQL Functions
2274 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
9fd8cb36
SM
2275"ascii" "avg" "bdmpolyfromtext" "bdmpolyfromwkb" "bdpolyfromtext"
2276"bdpolyfromwkb" "benchmark" "bin" "bit_and" "bit_length" "bit_or"
2277"bit_xor" "both" "cast" "char_length" "character_length" "coalesce"
2278"concat" "concat_ws" "connection_id" "conv" "convert" "count"
2279"curdate" "current_date" "current_time" "current_timestamp" "curtime"
2280"elt" "encrypt" "export_set" "field" "find_in_set" "found_rows" "from"
2281"geomcollfromtext" "geomcollfromwkb" "geometrycollectionfromtext"
2282"geometrycollectionfromwkb" "geometryfromtext" "geometryfromwkb"
2283"geomfromtext" "geomfromwkb" "get_lock" "group_concat" "hex" "ifnull"
2284"instr" "interval" "isnull" "last_insert_id" "lcase" "leading"
2285"length" "linefromtext" "linefromwkb" "linestringfromtext"
2286"linestringfromwkb" "load_file" "locate" "lower" "lpad" "ltrim"
2287"make_set" "master_pos_wait" "max" "mid" "min" "mlinefromtext"
2288"mlinefromwkb" "mpointfromtext" "mpointfromwkb" "mpolyfromtext"
2289"mpolyfromwkb" "multilinestringfromtext" "multilinestringfromwkb"
2290"multipointfromtext" "multipointfromwkb" "multipolygonfromtext"
2291"multipolygonfromwkb" "now" "nullif" "oct" "octet_length" "ord"
2292"pointfromtext" "pointfromwkb" "polyfromtext" "polyfromwkb"
2293"polygonfromtext" "polygonfromwkb" "position" "quote" "rand"
2294"release_lock" "repeat" "replace" "reverse" "rpad" "rtrim" "soundex"
2295"space" "std" "stddev" "substring" "substring_index" "sum" "sysdate"
2296"trailing" "trim" "ucase" "unix_timestamp" "upper" "user" "variance"
7492acc9 2297)
9fd8cb36 2298
7492acc9
MM
2299 ;; MySQL Keywords
2300 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
9fd8cb36
SM
2301"action" "add" "after" "against" "all" "alter" "and" "as" "asc"
2302"auto_increment" "avg_row_length" "bdb" "between" "by" "cascade"
2303"case" "change" "character" "check" "checksum" "close" "collate"
2304"collation" "column" "columns" "comment" "committed" "concurrent"
2305"constraint" "create" "cross" "data" "database" "default"
2306"delay_key_write" "delayed" "delete" "desc" "directory" "disable"
bb5aa5d6 2307"distinct" "distinctrow" "do" "drop" "dumpfile" "duplicate" "else" "elseif"
9fd8cb36
SM
2308"enable" "enclosed" "end" "escaped" "exists" "fields" "first" "for"
2309"force" "foreign" "from" "full" "fulltext" "global" "group" "handler"
2310"having" "heap" "high_priority" "if" "ignore" "in" "index" "infile"
2311"inner" "insert" "insert_method" "into" "is" "isam" "isolation" "join"
2312"key" "keys" "last" "left" "level" "like" "limit" "lines" "load"
2313"local" "lock" "low_priority" "match" "max_rows" "merge" "min_rows"
2314"mode" "modify" "mrg_myisam" "myisam" "natural" "next" "no" "not"
2315"null" "offset" "oj" "on" "open" "optionally" "or" "order" "outer"
2316"outfile" "pack_keys" "partial" "password" "prev" "primary"
2317"procedure" "quick" "raid0" "raid_type" "read" "references" "rename"
2318"repeatable" "restrict" "right" "rollback" "rollup" "row_format"
2319"savepoint" "select" "separator" "serializable" "session" "set"
2320"share" "show" "sql_big_result" "sql_buffer_result" "sql_cache"
2321"sql_calc_found_rows" "sql_no_cache" "sql_small_result" "starting"
2322"straight_join" "striped" "table" "tables" "temporary" "terminated"
2323"then" "to" "transaction" "truncate" "type" "uncommitted" "union"
2324"unique" "unlock" "update" "use" "using" "values" "when" "where"
2325"with" "write" "xor"
7492acc9 2326)
9fd8cb36 2327
7492acc9
MM
2328 ;; MySQL Data Types
2329 (sql-font-lock-keywords-builder 'font-lock-type-face nil
9fd8cb36
SM
2330"bigint" "binary" "bit" "blob" "bool" "boolean" "char" "curve" "date"
2331"datetime" "dec" "decimal" "double" "enum" "fixed" "float" "geometry"
2332"geometrycollection" "int" "integer" "line" "linearring" "linestring"
2333"longblob" "longtext" "mediumblob" "mediumint" "mediumtext"
2334"multicurve" "multilinestring" "multipoint" "multipolygon"
2335"multisurface" "national" "numeric" "point" "polygon" "precision"
2336"real" "smallint" "surface" "text" "time" "timestamp" "tinyblob"
2337"tinyint" "tinytext" "unsigned" "varchar" "year" "year2" "year4"
2338"zerofill"
2339)))
2340
78024f88
AS
2341 "MySQL SQL keywords used by font-lock.
2342
2343This variable is used by `sql-mode' and `sql-interactive-mode'. The
2344regular expressions are created during compilation by calling the
2345function `regexp-opt'. Therefore, take a look at the source before
063c6324 2346you define your own `sql-mode-mysql-font-lock-keywords'.")
78024f88 2347
b93d4f22
MM
2348(defvar sql-mode-sqlite-font-lock-keywords
2349 (eval-when-compile
2350 (list
9250002f
MM
2351 ;; SQLite commands
2352 '("^[.].*$" . font-lock-doc-face)
2353
b93d4f22
MM
2354 ;; SQLite Keyword
2355 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
2356"abort" "action" "add" "after" "all" "alter" "analyze" "and" "as"
2357"asc" "attach" "autoincrement" "before" "begin" "between" "by"
2358"cascade" "case" "cast" "check" "collate" "column" "commit" "conflict"
3bd2cfef
MM
2359"constraint" "create" "cross" "database" "default" "deferrable"
2360"deferred" "delete" "desc" "detach" "distinct" "drop" "each" "else"
2361"end" "escape" "except" "exclusive" "exists" "explain" "fail" "for"
b93d4f22
MM
2362"foreign" "from" "full" "glob" "group" "having" "if" "ignore"
2363"immediate" "in" "index" "indexed" "initially" "inner" "insert"
2364"instead" "intersect" "into" "is" "isnull" "join" "key" "left" "like"
2365"limit" "match" "natural" "no" "not" "notnull" "null" "of" "offset"
2366"on" "or" "order" "outer" "plan" "pragma" "primary" "query" "raise"
2367"references" "regexp" "reindex" "release" "rename" "replace"
2368"restrict" "right" "rollback" "row" "savepoint" "select" "set" "table"
2369"temp" "temporary" "then" "to" "transaction" "trigger" "union"
2370"unique" "update" "using" "vacuum" "values" "view" "virtual" "when"
2371"where"
2372)
2373 ;; SQLite Data types
2374 (sql-font-lock-keywords-builder 'font-lock-type-face nil
2375"int" "integer" "tinyint" "smallint" "mediumint" "bigint" "unsigned"
3bd2cfef 2376"big" "int2" "int8" "character" "varchar" "varying" "nchar" "native"
b93d4f22 2377"nvarchar" "text" "clob" "blob" "real" "double" "precision" "float"
3bd2cfef 2378"numeric" "number" "decimal" "boolean" "date" "datetime"
b93d4f22
MM
2379)
2380 ;; SQLite Functions
2381 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
2382;; Core functions
2383"abs" "changes" "coalesce" "glob" "ifnull" "hex" "last_insert_rowid"
2384"length" "like" "load_extension" "lower" "ltrim" "max" "min" "nullif"
2385"quote" "random" "randomblob" "replace" "round" "rtrim" "soundex"
2386"sqlite_compileoption_get" "sqlite_compileoption_used"
2387"sqlite_source_id" "sqlite_version" "substr" "total_changes" "trim"
2388"typeof" "upper" "zeroblob"
2389;; Date/time functions
2390"time" "julianday" "strftime"
3bd2cfef 2391"current_date" "current_time" "current_timestamp"
b93d4f22
MM
2392;; Aggregate functions
2393"avg" "count" "group_concat" "max" "min" "sum" "total"
2394)))
2395
78024f88
AS
2396 "SQLite SQL keywords used by font-lock.
2397
2398This variable is used by `sql-mode' and `sql-interactive-mode'. The
2399regular expressions are created during compilation by calling the
2400function `regexp-opt'. Therefore, take a look at the source before
063c6324 2401you define your own `sql-mode-sqlite-font-lock-keywords'.")
78024f88 2402
9fd8cb36 2403(defvar sql-mode-db2-font-lock-keywords nil
78024f88
AS
2404 "DB2 SQL keywords used by font-lock.
2405
2406This variable is used by `sql-mode' and `sql-interactive-mode'. The
2407regular expressions are created during compilation by calling the
2408function `regexp-opt'. Therefore, take a look at the source before
063c6324 2409you define your own `sql-mode-db2-font-lock-keywords'.")
78024f88
AS
2410
2411(defvar sql-mode-font-lock-keywords nil
95e4b2ef
RS
2412 "SQL keywords used by font-lock.
2413
78024f88
AS
2414Setting this variable directly no longer has any affect. Use
2415`sql-product' and `sql-add-product-keywords' to control the
063c6324 2416highlighting rules in SQL mode.")
78024f88
AS
2417
2418\f
2419
2420;;; SQL Product support functions
2421
74790210
MM
2422(defun sql-read-product (prompt &optional initial)
2423 "Read a valid SQL product."
2424 (let ((init (or (and initial (symbol-name initial)) "ansi")))
2425 (intern (completing-read
2426 prompt
2427 (mapcar (lambda (info) (symbol-name (car info)))
2428 sql-product-alist)
2429 nil 'require-match
2430 init 'sql-product-history init))))
2431
7492acc9
MM
2432(defun sql-add-product (product display &rest plist)
2433 "Add support for a database product in `sql-mode'.
2434
2435Add PRODUCT to `sql-product-alist' which enables `sql-mode' to
2436properly support syntax highlighting and interactive interaction.
2437DISPLAY is the name of the SQL product that will appear in the
2438menu bar and in messages. PLIST initializes the product
2439configuration."
2440
2441 ;; Don't do anything if the product is already supported
2442 (if (assoc product sql-product-alist)
2443 (message "Product `%s' is already defined" product)
2444
2445 ;; Add product to the alist
2446 (add-to-list 'sql-product-alist `((,product :name ,display . ,plist)))
2447 ;; Add a menu item to the SQL->Product menu
2448 (easy-menu-add-item sql-mode-menu '("Product")
2449 ;; Each product is represented by a radio
2450 ;; button with it's display name.
2451 `[,display
d26b0ea9 2452 (sql-set-product ',product)
7492acc9
MM
2453 :style radio
2454 :selected (eq sql-product ',product)]
2455 ;; Maintain the product list in
2456 ;; (case-insensitive) alphabetic order of the
2457 ;; display names. Loop thru each keymap item
2458 ;; looking for an item whose display name is
2459 ;; after this product's name.
2460 (let ((next-item)
2461 (down-display (downcase display)))
2462 (map-keymap (lambda (k b)
2463 (when (and (not next-item)
2464 (string-lessp down-display
2465 (downcase (cadr b))))
2466 (setq next-item k)))
2467 (easy-menu-get-map sql-mode-menu '("Product")))
2468 next-item))
2469 product))
2470
2471(defun sql-del-product (product)
2472 "Remove support for PRODUCT in `sql-mode'."
2473
2474 ;; Remove the menu item based on the display name
2475 (easy-menu-remove-item sql-mode-menu '("Product") (sql-get-product-feature product :name))
2476 ;; Remove the product alist item
2477 (setq sql-product-alist (assq-delete-all product sql-product-alist))
2478 nil)
2479
2480(defun sql-set-product-feature (product feature newvalue)
2481 "Set FEATURE of database PRODUCT to NEWVALUE.
2482
2483The PRODUCT must be a symbol which identifies the database
2484product. The product must have already exist on the product
2485list. See `sql-add-product' to add new products. The FEATURE
2486argument must be a plist keyword accepted by
2487`sql-product-alist'."
2488
2489 (let* ((p (assoc product sql-product-alist))
2490 (v (plist-get (cdr p) feature)))
2491 (if p
2492 (if (and
2493 (member feature sql-indirect-features)
2494 (symbolp v))
2495 (set v newvalue)
2496 (setcdr p (plist-put (cdr p) feature newvalue)))
2497 (message "`%s' is not a known product; use `sql-add-product' to add it first." product))))
2498
30c4d8dc 2499(defun sql-get-product-feature (product feature &optional fallback not-indirect)
7492acc9
MM
2500 "Lookup FEATURE associated with a SQL PRODUCT.
2501
2502If the FEATURE is nil for PRODUCT, and FALLBACK is specified,
2503then the FEATURE associated with the FALLBACK product is
2504returned.
78024f88 2505
30c4d8dc
MM
2506If the FEATURE is in the list `sql-indirect-features', and the
2507NOT-INDIRECT parameter is not set, then the value of the symbol
2508stored in the connect alist is returned.
2509
063c6324 2510See `sql-product-alist' for a list of products and supported features."
7492acc9
MM
2511 (let* ((p (assoc product sql-product-alist))
2512 (v (plist-get (cdr p) feature)))
2513
2514 (if p
2515 ;; If no value and fallback, lookup feature for fallback
2516 (if (and (not v)
2517 fallback
2518 (not (eq product fallback)))
2519 (sql-get-product-feature fallback feature)
2520
2521 (if (and
2522 (member feature sql-indirect-features)
30c4d8dc 2523 (not not-indirect)
7492acc9
MM
2524 (symbolp v))
2525 (symbol-value v)
2526 v))
d26b0ea9
MM
2527 (message "`%s' is not a known product; use `sql-add-product' to add it first." product)
2528 nil)))
78024f88
AS
2529
2530(defun sql-product-font-lock (keywords-only imenu)
c38762fd 2531 "Configure font-lock and imenu with product-specific settings.
7492acc9
MM
2532
2533The KEYWORDS-ONLY flag is passed to font-lock to specify whether
e4769531 2534only keywords should be highlighted and syntactic highlighting
7492acc9
MM
2535skipped. The IMENU flag indicates whether `imenu-mode' should
2536also be configured."
2537
78024f88
AS
2538 (let
2539 ;; Get the product-specific syntax-alist.
fbcc67e2 2540 ((syntax-alist (sql-product-font-lock-syntax-alist)))
78024f88
AS
2541
2542 ;; Get the product-specific keywords.
175069ef
SM
2543 (set (make-local-variable 'sql-mode-font-lock-keywords)
2544 (append
2545 (unless (eq sql-product 'ansi)
2546 (sql-get-product-feature sql-product :font-lock))
2547 ;; Always highlight ANSI keywords
2548 (sql-get-product-feature 'ansi :font-lock)
2549 ;; Fontify object names in CREATE, DROP and ALTER DDL
2550 ;; statements
2551 (list sql-mode-font-lock-object-name)))
78024f88 2552
9a9069c9 2553 ;; Setup font-lock. Force re-parsing of `font-lock-defaults'.
7492acc9 2554 (kill-local-variable 'font-lock-set-defaults)
175069ef
SM
2555 (set (make-local-variable 'font-lock-defaults)
2556 (list 'sql-mode-font-lock-keywords
2557 keywords-only t syntax-alist))
78024f88 2558
9a9069c9
SM
2559 ;; Force font lock to reinitialize if it is already on
2560 ;; Otherwise, we can wait until it can be started.
2561 (when (and (fboundp 'font-lock-mode)
7492acc9 2562 (boundp 'font-lock-mode)
9a9069c9
SM
2563 font-lock-mode)
2564 (font-lock-mode-internal nil)
2565 (font-lock-mode-internal t))
2566
2567 (add-hook 'font-lock-mode-hook
2568 (lambda ()
2569 ;; Provide defaults for new font-lock faces.
2570 (defvar font-lock-builtin-face
2571 (if (boundp 'font-lock-preprocessor-face)
2572 font-lock-preprocessor-face
2573 font-lock-keyword-face))
2574 (defvar font-lock-doc-face font-lock-string-face))
2575 nil t)
2576
78024f88
AS
2577 ;; Setup imenu; it needs the same syntax-alist.
2578 (when imenu
7492acc9 2579 (setq imenu-syntax-alist syntax-alist))))
78024f88
AS
2580
2581;;;###autoload
9fd8cb36
SM
2582(defun sql-add-product-keywords (product keywords &optional append)
2583 "Add highlighting KEYWORDS for SQL PRODUCT.
2584
c38762fd 2585PRODUCT should be a symbol, the name of a SQL product, such as
9fd8cb36
SM
2586`oracle'. KEYWORDS should be a list; see the variable
2587`font-lock-keywords'. By default they are added at the beginning
2588of the current highlighting list. If optional argument APPEND is
2589`set', they are used to replace the current highlighting list.
2590If APPEND is any other non-nil value, they are added at the end
2591of the current highlighting list.
2592
2593For example:
2594
2595 (sql-add-product-keywords 'ms
2596 '((\"\\\\b\\\\w+_t\\\\b\" . font-lock-type-face)))
2597
2598adds a fontification pattern to fontify identifiers ending in
2599`_t' as data types."
2600
7492acc9
MM
2601 (let* ((sql-indirect-features nil)
2602 (font-lock-var (sql-get-product-feature product :font-lock))
2603 (old-val))
2604
2605 (setq old-val (symbol-value font-lock-var))
2606 (set font-lock-var
9fd8cb36
SM
2607 (if (eq append 'set)
2608 keywords
2609 (if append
7492acc9
MM
2610 (append old-val keywords)
2611 (append keywords old-val))))))
95e4b2ef 2612
5474c40f
MM
2613(defun sql-for-each-login (login-params body)
2614 "Iterates through login parameters and returns a list of results."
2615
2616 (delq nil
2617 (mapcar
2618 (lambda (param)
2619 (let ((token (or (and (listp param) (car param)) param))
74790210 2620 (plist (or (and (listp param) (cdr param)) nil)))
5474c40f 2621
74790210 2622 (funcall body token plist)))
5474c40f
MM
2623 login-params)))
2624
95e4b2ef 2625\f
c0bbaf57 2626
624ef9b3
GM
2627;;; Functions to switch highlighting
2628
fbcc67e2
MM
2629(defun sql-product-syntax-table ()
2630 (let ((table (copy-syntax-table sql-mode-syntax-table)))
2631 (mapc (lambda (entry)
2632 (modify-syntax-entry (car entry) (cdr entry) table))
2633 (sql-get-product-feature sql-product :syntax-alist))
2634 table))
2635
2636(defun sql-product-font-lock-syntax-alist ()
2637 (append
2638 ;; Change all symbol character to word characters
2639 (mapcar
2640 (lambda (entry) (if (string= (substring (cdr entry) 0 1) "_")
2641 (cons (car entry)
2642 (concat "w" (substring (cdr entry) 1)))
2643 entry))
2644 (sql-get-product-feature sql-product :syntax-alist))
2645 '((?_ . "w"))))
2646
78024f88 2647(defun sql-highlight-product ()
c38762fd 2648 "Turn on the font highlighting for the SQL product selected."
55659495 2649 (when (derived-mode-p 'sql-mode)
fbcc67e2
MM
2650 ;; Enhance the syntax table for the product
2651 (set-syntax-table (sql-product-syntax-table))
2652
78024f88
AS
2653 ;; Setup font-lock
2654 (sql-product-font-lock nil t)
2655
78024f88 2656 ;; Set the mode name to include the product.
7492acc9
MM
2657 (setq mode-name (concat "SQL[" (or (sql-get-product-feature sql-product :name)
2658 (symbol-name sql-product)) "]"))))
78024f88
AS
2659
2660(defun sql-set-product (product)
c38762fd 2661 "Set `sql-product' to PRODUCT and enable appropriate highlighting."
55659495 2662 (interactive
74790210 2663 (list (sql-read-product "SQL product: ")))
55659495 2664 (if (stringp product) (setq product (intern product)))
9fd8cb36 2665 (when (not (assoc product sql-product-alist))
78024f88
AS
2666 (error "SQL product %s is not supported; treated as ANSI" product)
2667 (setq product 'ansi))
2668
2669 ;; Save product setting and fontify.
2670 (setq sql-product product)
2671 (sql-highlight-product))
624ef9b3
GM
2672\f
2673
04231ab8
MB
2674;;; Compatibility functions
2675
2676(if (not (fboundp 'comint-line-beginning-position))
2677 ;; comint-line-beginning-position is defined in Emacs 21
2678 (defun comint-line-beginning-position ()
063c6324 2679 "Return the buffer position of the beginning of the line, after any prompt.
fbcc67e2
MM
2680The prompt is assumed to be any text at the beginning of the line
2681matching the regular expression `comint-prompt-regexp', a buffer
2682local variable."
04231ab8
MB
2683 (save-excursion (comint-bol nil) (point))))
2684
fbcc67e2
MM
2685;;; Motion Functions
2686
2687(defun sql-statement-regexp (prod)
2688 (let* ((ansi-stmt (sql-get-product-feature 'ansi :statement))
2689 (prod-stmt (sql-get-product-feature prod :statement)))
2690 (concat "^\\<"
2691 (if prod-stmt
2692 ansi-stmt
2693 (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)"))
2694 "\\>")))
2695
2696(defun sql-beginning-of-statement (arg)
2697 "Moves the cursor to the beginning of the current SQL statement."
2698 (interactive "p")
2699
2700 (let ((here (point))
2701 (regexp (sql-statement-regexp sql-product))
2702 last next)
2703
2704 ;; Go to the end of the statement before the start we desire
2705 (setq last (or (sql-end-of-statement (- arg))
2706 (point-min)))
2707 ;; And find the end after that
2708 (setq next (or (sql-end-of-statement 1)
2709 (point-max)))
2710
2711 ;; Our start must be between them
2712 (goto-char last)
2713 ;; Find an beginning-of-stmt that's not in a comment
2714 (while (and (re-search-forward regexp next t 1)
2715 (nth 7 (syntax-ppss)))
2716 (goto-char (match-end 0)))
2717 (goto-char
2718 (if (match-data)
2719 (match-beginning 0)
2720 last))
2721 (beginning-of-line)
2722 ;; If we didn't move, try again
2723 (when (= here (point))
2724 (sql-beginning-of-statement (* 2 (sql-signum arg))))))
2725
2726(defun sql-end-of-statement (arg)
2727 "Moves the cursor to the end of the current SQL statement."
2728 (interactive "p")
2729 (let ((term (sql-get-product-feature sql-product :terminator))
2730 (re-search (if (> 0 arg) 're-search-backward 're-search-forward))
2731 (here (point))
2732 (n 0))
2733 (when (consp term)
2734 (setq term (car term)))
2735 ;; Iterate until we've moved the desired number of stmt ends
2736 (while (not (= (sql-signum arg) 0))
2737 ;; if we're looking at the terminator, jump by 2
2738 (if (or (and (> 0 arg) (looking-back term))
2739 (and (< 0 arg) (looking-at term)))
2740 (setq n 2)
2741 (setq n 1))
2742 ;; If we found another end-of-stmt
2743 (if (not (apply re-search term nil t n nil))
2744 (setq arg 0)
2745 ;; count it if we're not in a comment
2746 (unless (nth 7 (syntax-ppss))
2747 (setq arg (- arg (sql-signum arg))))))
2748 (goto-char (if (match-data)
2749 (match-end 0)
2750 here))))
95e4b2ef
RS
2751
2752;;; Small functions
2753
9ef3882f
GM
2754(defun sql-magic-go (arg)
2755 "Insert \"o\" and call `comint-send-input'.
2756`sql-electric-stuff' must be the symbol `go'."
2757 (interactive "P")
2758 (self-insert-command (prefix-numeric-value arg))
2759 (if (and (equal sql-electric-stuff 'go)
2760 (save-excursion
3035b156
MB
2761 (comint-bol nil)
2762 (looking-at "go\\b")))
9ef3882f
GM
2763 (comint-send-input)))
2764
2765(defun sql-magic-semicolon (arg)
2766 "Insert semicolon and call `comint-send-input'.
2767`sql-electric-stuff' must be the symbol `semicolon'."
2768 (interactive "P")
2769 (self-insert-command (prefix-numeric-value arg))
2770 (if (equal sql-electric-stuff 'semicolon)
2771 (comint-send-input)))
2772
95e4b2ef
RS
2773(defun sql-accumulate-and-indent ()
2774 "Continue SQL statement on the next line."
2775 (interactive)
f4df536d 2776 (if (fboundp 'comint-accumulate)
9ef3882f
GM
2777 (comint-accumulate)
2778 (newline))
95e4b2ef
RS
2779 (indent-according-to-mode))
2780
7492acc9
MM
2781(defun sql-help-list-products (indent freep)
2782 "Generate listing of products available for use under SQLi.
2783
fbcc67e2 2784List products with :free-software attribute set to FREEP. Indent
7492acc9
MM
2785each line with INDENT."
2786
2787 (let (sqli-func doc)
2788 (setq doc "")
2789 (dolist (p sql-product-alist)
2790 (setq sqli-func (intern (concat "sql-" (symbol-name (car p)))))
2791
2792 (if (and (fboundp sqli-func)
2793 (eq (sql-get-product-feature (car p) :free-software) freep))
2794 (setq doc
2795 (concat doc
2796 indent
2797 (or (sql-get-product-feature (car p) :name)
2798 (symbol-name (car p)))
2799 ":\t"
2800 "\\["
2801 (symbol-name sqli-func)
2802 "]\n"))))
2803 doc))
2804
95e4b2ef
RS
2805;;;###autoload
2806(defun sql-help ()
801d1cb0 2807 "Show short help for the SQL modes.
95e4b2ef
RS
2808
2809Use an entry function to open an interactive SQL buffer. This buffer is
dab100d7 2810usually named `*SQL*'. The name of the major mode is SQLi.
95e4b2ef
RS
2811
2812Use the following commands to start a specific SQL interpreter:
2813
7492acc9 2814 \\\\FREE
50842164
RS
2815
2816Other non-free SQL implementations are also supported:
2817
7492acc9 2818 \\\\NONFREE
50842164
RS
2819
2820But we urge you to choose a free implementation instead of these.
95e4b2ef 2821
7492acc9
MM
2822You can also use \\[sql-product-interactive] to invoke the
2823interpreter for the current `sql-product'.
2824
95e4b2ef
RS
2825Once you have the SQLi buffer, you can enter SQL statements in the
2826buffer. The output generated is appended to the buffer and a new prompt
2827is generated. See the In/Out menu in the SQLi buffer for some functions
2828that help you navigate through the buffer, the input history, etc.
2829
95e4b2ef
RS
2830If you have a really complex SQL statement or if you are writing a
2831procedure, you can do this in a separate buffer. Put the new buffer in
2832`sql-mode' by calling \\[sql-mode]. The name of this buffer can be
2833anything. The name of the major mode is SQL.
2834
2835In this SQL buffer (SQL mode), you can send the region or the entire
2836buffer to the interactive SQL buffer (SQLi mode). The results are
2837appended to the SQLi buffer without disturbing your SQL buffer."
2838 (interactive)
7492acc9
MM
2839
2840 ;; Insert references to loaded products into the help buffer string
2841 (let ((doc (documentation 'sql-help t))
2842 changedp)
2843 (setq changedp nil)
2844
2845 ;; Insert FREE software list
2846 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]FREE\\s-*\n" doc 0)
2847 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) t)
2848 t t doc 0)
2849 changedp t))
2850
2851 ;; Insert non-FREE software list
2852 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]NONFREE\\s-*\n" doc 0)
2853 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) nil)
2854 t t doc 0)
2855 changedp t))
2856
2857 ;; If we changed the help text, save the change so that the help
2858 ;; sub-system will see it
2859 (when changedp
2860 (put 'sql-help 'function-documentation doc)))
2861
2862 ;; Call help on this function
95e4b2ef
RS
2863 (describe-function 'sql-help))
2864
2865(defun sql-read-passwd (prompt &optional default)
8d68e9b5
RS
2866 "Read a password using PROMPT. Optional DEFAULT is password to start with."
2867 (read-passwd prompt nil default))
95e4b2ef 2868
f6561e1f 2869(defun sql-get-login-ext (symbol prompt history-var plist)
5474c40f
MM
2870 "Prompt user with extended login parameters.
2871
2bb1ae55 2872The global value of SYMBOL is the last value and the global value
f6561e1f
MM
2873of the SYMBOL is set based on the user's input.
2874
74790210 2875If PLIST is nil, then the user is simply prompted for a string
5474c40f
MM
2876value.
2877
74790210
MM
2878The property `:default' specifies the default value. If the
2879`:number' property is non-nil then ask for a number.
5474c40f 2880
74790210
MM
2881The `:file' property prompts for a file name that must match the
2882regexp pattern specified in its value.
5474c40f 2883
74790210
MM
2884The `:completion' property prompts for a string specified by its
2885value. (The property value is used as the PREDICATE argument to
2886`completing-read'.)"
2bb1ae55 2887 (set-default
f6561e1f
MM
2888 symbol
2889 (let* ((default (plist-get plist :default))
2890 (last-value (default-value symbol))
2891 (prompt-def
2892 (if default
2893 (if (string-match "\\(\\):[ \t]*\\'" prompt)
2894 (replace-match (format " (default \"%s\")" default) t t prompt 1)
2895 (replace-regexp-in-string "[ \t]*\\'"
2896 (format " (default \"%s\") " default)
2897 prompt t t))
2898 prompt))
2899 (use-dialog-box nil))
2900 (cond
2901 ((plist-member plist :file)
2902 (expand-file-name
2903 (read-file-name prompt
2904 (file-name-directory last-value) default t
2905 (file-name-nondirectory last-value)
2906 (when (plist-get plist :file)
2907 `(lambda (f)
2908 (string-match
2909 (concat "\\<" ,(plist-get plist :file) "\\>")
2910 (file-name-nondirectory f)))))))
2911
2912 ((plist-member plist :completion)
2913 (completing-read prompt-def (plist-get plist :completion) nil t
2914 last-value history-var default))
2915
2916 ((plist-get plist :number)
2917 (read-number prompt (or default last-value 0)))
2918
2919 (t
2920 (let ((r (read-from-minibuffer prompt-def last-value nil nil history-var nil)))
2921 (if (string= "" r) (or default "") r)))))))
5474c40f 2922
95e4b2ef
RS
2923(defun sql-get-login (&rest what)
2924 "Get username, password and database from the user.
2925
dab100d7 2926The variables `sql-user', `sql-password', `sql-server', and
eb3f61dd 2927`sql-database' can be customized. They are used as the default values.
dab100d7
RS
2928Usernames, servers and databases are stored in `sql-user-history',
2929`sql-server-history' and `database-history'. Passwords are not stored
2930in a history.
95e4b2ef 2931
7492acc9
MM
2932Parameter WHAT is a list of tokens passed as arguments in the
2933function call. The function asks for the username if WHAT
2934contains the symbol `user', for the password if it contains the
2935symbol `password', for the server if it contains the symbol
2936`server', and for the database if it contains the symbol
2937`database'. The members of WHAT are processed in the order in
2938which they are provided.
95e4b2ef 2939
74790210
MM
2940Each token may also be a list with the token in the car and a
2941plist of options as the cdr. The following properties are
2942supported:
5474c40f 2943
74790210
MM
2944 :file <filename-regexp>
2945 :completion <list-of-strings-or-function>
2946 :default <default-value>
2947 :number t
5474c40f 2948
95e4b2ef
RS
2949In order to ask the user for username, password and database, call the
2950function like this: (sql-get-login 'user 'password 'database)."
2951 (interactive)
74790210
MM
2952 (mapcar
2953 (lambda (w)
2954 (let ((token (or (and (consp w) (car w)) w))
2955 (plist (or (and (consp w) (cdr w)) nil)))
2956
2957 (cond
2958 ((eq token 'user) ; user
f6561e1f 2959 (sql-get-login-ext 'sql-user "User: " 'sql-user-history plist))
74790210 2960
f6561e1f
MM
2961 ((eq token 'password) ; password
2962 (setq-default sql-password
2963 (sql-read-passwd "Password: " sql-password)))
74790210 2964
f6561e1f
MM
2965 ((eq token 'server) ; server
2966 (sql-get-login-ext 'sql-server "Server: " 'sql-server-history plist))
74790210 2967
f6561e1f
MM
2968 ((eq token 'database) ; database
2969 (sql-get-login-ext 'sql-database "Database: " 'sql-database-history plist))
74790210
MM
2970
2971 ((eq token 'port) ; port
f6561e1f 2972 (sql-get-login-ext 'sql-port "Port: " nil (append '(:number t) plist))))))
74790210
MM
2973 what))
2974
fbcc67e2 2975(defun sql-find-sqli-buffer (&optional product connection)
9250002f
MM
2976 "Returns the name of the current default SQLi buffer or nil.
2977In order to qualify, the SQLi buffer must be alive, be in
2978`sql-interactive-mode' and have a process."
a386ac70 2979 (let ((buf sql-buffer)
74790210 2980 (prod (or product sql-product)))
a386ac70
MM
2981 (or
2982 ;; Current sql-buffer, if there is one.
fbcc67e2 2983 (and (sql-buffer-live-p buf prod connection)
a386ac70
MM
2984 buf)
2985 ;; Global sql-buffer
2986 (and (setq buf (default-value 'sql-buffer))
fbcc67e2 2987 (sql-buffer-live-p buf prod connection)
a386ac70
MM
2988 buf)
2989 ;; Look thru each buffer
2990 (car (apply 'append
2991 (mapcar (lambda (b)
fbcc67e2 2992 (and (sql-buffer-live-p b prod connection)
a386ac70
MM
2993 (list (buffer-name b))))
2994 (buffer-list)))))))
46d94d0d
GM
2995
2996(defun sql-set-sqli-buffer-generally ()
f4df536d 2997 "Set SQLi buffer for all SQL buffers that have none.
46d94d0d
GM
2998This function checks all SQL buffers for their SQLi buffer. If their
2999SQLi buffer is nonexistent or has no process, it is set to the current
3000default SQLi buffer. The current default SQLi buffer is determined
3001using `sql-find-sqli-buffer'. If `sql-buffer' is set,
3002`sql-set-sqli-hook' is run."
3003 (interactive)
3004 (save-excursion
3005 (let ((buflist (buffer-list))
9250002f
MM
3006 (default-buffer (sql-find-sqli-buffer)))
3007 (setq-default sql-buffer default-buffer)
46d94d0d
GM
3008 (while (not (null buflist))
3009 (let ((candidate (car buflist)))
3010 (set-buffer candidate)
55659495 3011 (if (and (derived-mode-p 'sql-mode)
a386ac70 3012 (not (sql-buffer-live-p sql-buffer)))
46d94d0d 3013 (progn
9250002f 3014 (setq sql-buffer default-buffer)
a386ac70
MM
3015 (when default-buffer
3016 (run-hooks 'sql-set-sqli-hook)))))
46d94d0d
GM
3017 (setq buflist (cdr buflist))))))
3018
c7055d66
RS
3019(defun sql-set-sqli-buffer ()
3020 "Set the SQLi buffer SQL strings are sent to.
95e4b2ef 3021
c7055d66
RS
3022Call this function in a SQL buffer in order to set the SQLi buffer SQL
3023strings are sent to. Calling this function sets `sql-buffer' and runs
3024`sql-set-sqli-hook'.
dab100d7 3025
c7055d66 3026If you call it from a SQL buffer, this sets the local copy of
801d1cb0 3027`sql-buffer'.
dab100d7 3028
c7055d66 3029If you call it from anywhere else, it sets the global copy of
dab100d7
RS
3030`sql-buffer'."
3031 (interactive)
46d94d0d
GM
3032 (let ((default-buffer (sql-find-sqli-buffer)))
3033 (if (null default-buffer)
a386ac70
MM
3034 (error "There is no suitable SQLi buffer")
3035 (let ((new-buffer (read-buffer "New SQLi buffer: " default-buffer t)))
3036 (if (null (sql-buffer-live-p new-buffer))
3037 (error "Buffer %s is not a working SQLi buffer" new-buffer)
3038 (when new-buffer
3039 (setq sql-buffer new-buffer)
3040 (run-hooks 'sql-set-sqli-hook)))))))
dab100d7
RS
3041
3042(defun sql-show-sqli-buffer ()
3043 "Show the name of current SQLi buffer.
3044
3045This is the buffer SQL strings are sent to. It is stored in the
3046variable `sql-buffer'. See `sql-help' on how to create such a buffer."
3047 (interactive)
fbcc67e2
MM
3048 (if (or (null sql-buffer)
3049 (null (buffer-live-p (get-buffer sql-buffer))))
c7055d66 3050 (message "%s has no SQLi buffer set." (buffer-name (current-buffer)))
dab100d7 3051 (if (null (get-buffer-process sql-buffer))
9250002f
MM
3052 (message "Buffer %s has no process." sql-buffer)
3053 (message "Current SQLi buffer is %s." sql-buffer))))
dab100d7 3054
c7055d66 3055(defun sql-make-alternate-buffer-name ()
c38762fd 3056 "Return a string that can be used to rename a SQLi buffer.
c7055d66
RS
3057
3058This is used to set `sql-alternate-buffer-name' within
30c4d8dc
MM
3059`sql-interactive-mode'.
3060
3061If the session was started with `sql-connect' then the alternate
3062name would be the name of the connection.
3063
3064Otherwise, it uses the parameters identified by the :sqlilogin
3065parameter.
3066
3067If all else fails, the alternate name would be the user and
3068server/database name."
3069
d26b0ea9
MM
3070 (let ((name ""))
3071
5474c40f
MM
3072 ;; Build a name using the :sqli-login setting
3073 (setq name
3074 (apply 'concat
3bd2cfef
MM
3075 (cdr
3076 (apply 'append nil
3077 (sql-for-each-login
3078 (sql-get-product-feature sql-product :sqli-login)
74790210 3079 (lambda (token plist)
3bd2cfef
MM
3080 (cond
3081 ((eq token 'user)
3082 (unless (string= "" sql-user)
3083 (list "/" sql-user)))
3084 ((eq token 'port)
9250002f
MM
3085 (unless (or (not (numberp sql-port))
3086 (= 0 sql-port))
3087 (list ":" (number-to-string sql-port))))
3bd2cfef
MM
3088 ((eq token 'server)
3089 (unless (string= "" sql-server)
3090 (list "."
74790210 3091 (if (plist-member plist :file)
3bd2cfef
MM
3092 (file-name-nondirectory sql-server)
3093 sql-server))))
3094 ((eq token 'database)
9250002f 3095 (unless (string= "" sql-database)
3bd2cfef 3096 (list "@"
74790210 3097 (if (plist-member plist :file)
3bd2cfef
MM
3098 (file-name-nondirectory sql-database)
3099 sql-database))))
3100
3101 ((eq token 'password) nil)
3102 (t nil))))))))
5474c40f
MM
3103
3104 ;; If there's a connection, use it and the name thus far
d26b0ea9
MM
3105 (if sql-connection
3106 (format "<%s>%s" sql-connection (or name ""))
5474c40f
MM
3107
3108 ;; If there is no name, try to create something meaningful
3109 (if (string= "" (or name ""))
3110 (concat
3111 (if (string= "" sql-user)
3112 (if (string= "" (user-login-name))
3113 ()
3114 (concat (user-login-name) "/"))
3115 (concat sql-user "/"))
3116 (if (string= "" sql-database)
3117 (if (string= "" sql-server)
3118 (system-name)
3119 sql-server)
3120 sql-database))
3121
3bd2cfef
MM
3122 ;; Use the name we've got
3123 name))))
c7055d66 3124
9250002f
MM
3125(defun sql-rename-buffer (&optional new-name)
3126 "Rename a SQL interactive buffer.
3127
0d327994 3128Prompts for the new name if command is preceded by
9250002f
MM
3129\\[universal-argument]. If no buffer name is provided, then the
3130`sql-alternate-buffer-name' is used.
3131
3132The actual buffer name set will be \"*SQL: NEW-NAME*\". If
3133NEW-NAME is empty, then the buffer name will be \"*SQL*\"."
3134 (interactive "P")
3135
3136 (if (not (derived-mode-p 'sql-interactive-mode))
3137 (message "Current buffer is not a SQL interactive buffer")
3138
a386ac70
MM
3139 (setq sql-alternate-buffer-name
3140 (cond
3141 ((stringp new-name) new-name)
3142 ((consp new-name)
9250002f 3143 (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): "
a386ac70
MM
3144 sql-alternate-buffer-name))
3145 (t sql-alternate-buffer-name)))
9250002f
MM
3146
3147 (rename-buffer (if (string= "" sql-alternate-buffer-name)
3148 "*SQL*"
3149 (format "*SQL: %s*" sql-alternate-buffer-name))
3150 t)))
c7055d66 3151
95e4b2ef
RS
3152(defun sql-copy-column ()
3153 "Copy current column to the end of buffer.
3154Inserts SELECT or commas if appropriate."
3155 (interactive)
3156 (let ((column))
3157 (save-excursion
7492acc9 3158 (setq column (buffer-substring-no-properties
95e4b2ef
RS
3159 (progn (forward-char 1) (backward-sexp 1) (point))
3160 (progn (forward-sexp 1) (point))))
3161 (goto-char (point-max))
3035b156
MB
3162 (let ((bol (comint-line-beginning-position)))
3163 (cond
3164 ;; if empty command line, insert SELECT
3165 ((= bol (point))
3166 (insert "SELECT "))
3167 ;; else if appending to INTO .* (, SELECT or ORDER BY, insert a comma
3168 ((save-excursion
3169 (re-search-backward "\\b\\(\\(into\\s-+\\S-+\\s-+(\\)\\|select\\|order by\\) .+"
3170 bol t))
3171 (insert ", "))
3172 ;; else insert a space
3173 (t
b9584f65 3174 (if (eq (preceding-char) ?\s)
3035b156
MB
3175 nil
3176 (insert " ")))))
95e4b2ef
RS
3177 ;; in any case, insert the column
3178 (insert column)
3179 (message "%s" column))))
3180
063c6324
JB
3181;; On Windows, SQL*Plus for Oracle turns on full buffering for stdout
3182;; if it is not attached to a character device; therefore placeholder
77d352a6
GM
3183;; replacement by SQL*Plus is fully buffered. The workaround lets
3184;; Emacs query for the placeholders.
3185
3186(defvar sql-placeholder-history nil
3187 "History of placeholder values used.")
3188
7492acc9
MM
3189(defun sql-placeholders-filter (string)
3190 "Replace placeholders in STRING.
c38762fd 3191Placeholders are words starting with an ampersand like &this."
7492acc9
MM
3192
3193 (when sql-oracle-scan-on
3194 (while (string-match "&\\(\\sw+\\)" string)
3195 (setq string (replace-match
3196 (read-from-minibuffer
3197 (format "Enter value for %s: " (match-string 1 string))
3198 nil nil nil 'sql-placeholder-history)
3199 t t string))))
3200 string)
77d352a6 3201
624ef9b3
GM
3202;; Using DB2 interactively, newlines must be escaped with " \".
3203;; The space before the backslash is relevant.
04e082b0 3204
7492acc9 3205(defun sql-escape-newlines-filter (string)
c38762fd 3206 "Escape newlines in STRING.
624ef9b3 3207Every newline in STRING will be preceded with a space and a backslash."
04e082b0
MM
3208 (if (not sql-db2-escape-newlines)
3209 string
3210 (let ((result "") (start 0) mb me)
3211 (while (string-match "\n" string start)
3212 (setq mb (match-beginning 0)
3213 me (match-end 0)
3214 result (concat result
3215 (substring string start mb)
3216 (if (and (> mb 1)
3217 (string-equal " \\" (substring string (- mb 2) mb)))
3218 "" " \\\n"))
3219 start me))
3220 (concat result (substring string start)))))
624ef9b3 3221
95e4b2ef
RS
3222\f
3223
7492acc9
MM
3224;;; Input sender for SQLi buffers
3225
3bd2cfef
MM
3226(defvar sql-output-newline-count 0
3227 "Number of newlines in the input string.
3228
3229Allows the suppression of continuation prompts.")
3230
3231(defvar sql-output-by-send nil
3232 "Non-nil if the command in the input was generated by `sql-send-string'.")
3233
7492acc9 3234(defun sql-input-sender (proc string)
c38762fd 3235 "Send STRING to PROC after applying filters."
7492acc9
MM
3236
3237 (let* ((product (with-current-buffer (process-buffer proc) sql-product))
3238 (filter (sql-get-product-feature product :input-filter)))
3239
3bd2cfef
MM
3240 ;; Apply filter(s)
3241 (cond
3242 ((not filter)
3243 nil)
3244 ((functionp filter)
3245 (setq string (funcall filter string)))
3246 ((listp filter)
3247 (mapc (lambda (f) (setq string (funcall f string))) filter))
3248 (t nil))
3249
3250 ;; Count how many newlines in the string
3251 (setq sql-output-newline-count 0)
3252 (mapc (lambda (ch)
3253 (when (eq ch ?\n)
3254 (setq sql-output-newline-count (1+ sql-output-newline-count))))
3255 string)
3256
7492acc9 3257 ;; Send the string
3bd2cfef
MM
3258 (comint-simple-send proc string)))
3259
3260;;; Strip out continuation prompts
3261
fbcc67e2
MM
3262(defvar sql-preoutput-hold nil)
3263
3bd2cfef
MM
3264(defun sql-interactive-remove-continuation-prompt (oline)
3265 "Strip out continuation prompts out of the OLINE.
3266
3267Added to the `comint-preoutput-filter-functions' hook in a SQL
fbcc67e2 3268interactive buffer. If `sql-output-newline-count' is greater than
3bd2cfef 3269zero, then an output line matching the continuation prompt is filtered
fbcc67e2
MM
3270out. If the count is zero, then a newline is inserted into the output
3271to force the output from the query to appear on a new line.
3272
3273The complication to this filter is that the continuation prompts
3274may arrive in multiple chunks. If they do, then the function
3275saves any unfiltered output in a buffer and prepends that buffer
3276to the next chunk to properly match the broken-up prompt.
3277
3278If the filter gets confused, it should reset and stop filtering
3279to avoid deleting non-prompt output."
3280
3281 (let (did-filter)
3282 (setq oline (concat (or sql-preoutput-hold "") oline)
3283 sql-preoutput-hold nil)
3284
3285 (if (and comint-prompt-regexp
3286 (integerp sql-output-newline-count)
3287 (>= sql-output-newline-count 1))
3288 (progn
3289 (while (and (not (string= oline ""))
3290 (> sql-output-newline-count 0)
3291 (string-match comint-prompt-regexp oline)
3292 (= (match-beginning 0) 0))
3293
3294 (setq oline (replace-match "" nil nil oline)
3295 sql-output-newline-count (1- sql-output-newline-count)
3296 did-filter t))
3297
3298 (if (= sql-output-newline-count 0)
3299 (setq sql-output-newline-count nil
3300 oline (concat "\n" oline)
3301 sql-output-by-send nil)
3302
3303 (setq sql-preoutput-hold oline
3304 oline ""))
3305
3306 (unless did-filter
3307 (setq oline (or sql-preoutput-hold "")
3308 sql-preoutput-hold nil
3309 sql-output-newline-count nil)))
3310
3311 (setq sql-output-newline-count nil))
3312
3313 oline))
7492acc9 3314
95e4b2ef
RS
3315;;; Sending the region to the SQLi buffer.
3316
7492acc9
MM
3317(defun sql-send-string (str)
3318 "Send the string STR to the SQL process."
3319 (interactive "sSQL Text: ")
3320
3bd2cfef
MM
3321 (let ((comint-input-sender-no-newline nil)
3322 (s (replace-regexp-in-string "[[:space:]\n\r]+\\'" "" str)))
9250002f 3323 (if (sql-buffer-live-p sql-buffer)
7492acc9
MM
3324 (progn
3325 ;; Ignore the hoping around...
3326 (save-excursion
7492acc9
MM
3327 ;; Set product context
3328 (with-current-buffer sql-buffer
3bd2cfef
MM
3329 ;; Send the string (trim the trailing whitespace)
3330 (sql-input-sender (get-buffer-process sql-buffer) s)
7492acc9
MM
3331
3332 ;; Send a command terminator if we must
3333 (if sql-send-terminator
3bd2cfef 3334 (sql-send-magic-terminator sql-buffer s sql-send-terminator))
7492acc9 3335
9250002f 3336 (message "Sent string to buffer %s." sql-buffer)))
7492acc9
MM
3337
3338 ;; Display the sql buffer
3339 (if sql-pop-to-buffer-after-send-region
3340 (pop-to-buffer sql-buffer)
3341 (display-buffer sql-buffer)))
3342
3343 ;; We don't have no stinkin' sql
3344 (message "No SQL process started."))))
3345
95e4b2ef
RS
3346(defun sql-send-region (start end)
3347 "Send a region to the SQL process."
3348 (interactive "r")
7492acc9 3349 (sql-send-string (buffer-substring-no-properties start end)))
95e4b2ef 3350
dab100d7
RS
3351(defun sql-send-paragraph ()
3352 "Send the current paragraph to the SQL process."
3353 (interactive)
3354 (let ((start (save-excursion
3355 (backward-paragraph)
3356 (point)))
3357 (end (save-excursion
3358 (forward-paragraph)
3359 (point))))
3360 (sql-send-region start end)))
3361
95e4b2ef
RS
3362(defun sql-send-buffer ()
3363 "Send the buffer contents to the SQL process."
3364 (interactive)
3365 (sql-send-region (point-min) (point-max)))
3366
7492acc9 3367(defun sql-send-magic-terminator (buf str terminator)
c38762fd 3368 "Send TERMINATOR to buffer BUF if its not present in STR."
3bd2cfef 3369 (let (comint-input-sender-no-newline pat term)
7492acc9
MM
3370 ;; If flag is merely on(t), get product-specific terminator
3371 (if (eq terminator t)
3372 (setq terminator (sql-get-product-feature sql-product :terminator)))
3373
3374 ;; If there is no terminator specified, use default ";"
3375 (unless terminator
3376 (setq terminator ";"))
3377
3378 ;; Parse the setting into the pattern and the terminator string
3379 (cond ((stringp terminator)
3380 (setq pat (regexp-quote terminator)
3381 term terminator))
3382 ((consp terminator)
3383 (setq pat (car terminator)
3384 term (cdr terminator)))
3385 (t
3386 nil))
3387
3388 ;; Check to see if the pattern is present in the str already sent
3389 (unless (and pat term
3bd2cfef
MM
3390 (string-match (concat pat "\\'") str))
3391 (comint-simple-send (get-buffer-process buf) term)
3392 (setq sql-output-newline-count
3393 (if sql-output-newline-count
3394 (1+ sql-output-newline-count)
3395 1)))
3396 (setq sql-output-by-send t)))
7492acc9
MM
3397
3398(defun sql-remove-tabs-filter (str)
3399 "Replace tab characters with spaces."
3400 (replace-regexp-in-string "\t" " " str nil t))
9fd8cb36 3401
95e4b2ef
RS
3402(defun sql-toggle-pop-to-buffer-after-send-region (&optional value)
3403 "Toggle `sql-pop-to-buffer-after-send-region'.
3404
3405If given the optional parameter VALUE, sets
063c6324 3406`sql-toggle-pop-to-buffer-after-send-region' to VALUE."
95e4b2ef
RS
3407 (interactive "P")
3408 (if value
3409 (setq sql-pop-to-buffer-after-send-region value)
801d1cb0 3410 (setq sql-pop-to-buffer-after-send-region
7492acc9 3411 (null sql-pop-to-buffer-after-send-region))))
95e4b2ef
RS
3412
3413\f
3414
a386ac70
MM
3415;;; Redirect output functions
3416
fbcc67e2
MM
3417(defvar sql-debug-redirect nil
3418 "If non-nil, display messages related to the use of redirection.")
3419
3420(defun sql-str-literal (s)
3421 (concat "'" (replace-regexp-in-string "[']" "''" s) "'"))
3422
3423(defun sql-redirect (sqlbuf command &optional outbuf save-prior)
a386ac70
MM
3424 "Execute the SQL command and send output to OUTBUF.
3425
fbcc67e2 3426SQLBUF must be an active SQL interactive buffer. OUTBUF may be
a386ac70
MM
3427an existing buffer, or the name of a non-existing buffer. If
3428omitted the output is sent to a temporary buffer which will be
3429killed after the command completes. COMMAND should be a string
fbcc67e2
MM
3430of commands accepted by the SQLi program. COMMAND may also be a
3431list of SQLi command strings."
3432
3433 (let* ((visible (and outbuf
3434 (not (string= " " (substring outbuf 0 1))))))
3435 (when visible
3436 (message "Executing SQL command..."))
3437 (if (consp command)
3438 (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior))
3439 command)
3440 (sql-redirect-one sqlbuf command outbuf save-prior))
3441 (when visible
3442 (message "Executing SQL command...done"))))
3443
3444(defun sql-redirect-one (sqlbuf command outbuf save-prior)
3445 (with-current-buffer sqlbuf
a386ac70
MM
3446 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
3447 (proc (get-buffer-process (current-buffer)))
3448 (comint-prompt-regexp (sql-get-product-feature sql-product
3449 :prompt-regexp))
3450 (start nil))
3451 (with-current-buffer buf
bb5aa5d6 3452 (setq view-read-only nil)
a386ac70
MM
3453 (unless save-prior
3454 (erase-buffer))
3455 (goto-char (point-max))
74790210
MM
3456 (unless (zerop (buffer-size))
3457 (insert "\n"))
a386ac70
MM
3458 (setq start (point)))
3459
fbcc67e2
MM
3460 (when sql-debug-redirect
3461 (message ">>SQL> %S" command))
3462
a386ac70
MM
3463 ;; Run the command
3464 (comint-redirect-send-command-to-process command buf proc nil t)
3465 (while (null comint-redirect-completed)
3466 (accept-process-output nil 1))
3467
74790210 3468 ;; Clean up the output results
a386ac70 3469 (with-current-buffer buf
74790210
MM
3470 ;; Remove trailing whitespace
3471 (goto-char (point-max))
3472 (when (looking-back "[ \t\f\n\r]*" start)
3473 (delete-region (match-beginning 0) (match-end 0)))
3474 ;; Remove echo if there was one
a386ac70
MM
3475 (goto-char start)
3476 (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
3477 (delete-region (match-beginning 0) (match-end 0)))
fbcc67e2
MM
3478 ;; Remove Ctrl-Ms
3479 (goto-char start)
3480 (while (re-search-forward "\r+$" nil t)
3481 (replace-match "" t t))
a386ac70
MM
3482 (goto-char start)))))
3483
fbcc67e2 3484(defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups)
a386ac70
MM
3485 "Execute the SQL command and return part of result.
3486
fbcc67e2 3487SQLBUF must be an active SQL interactive buffer. COMMAND should
a386ac70
MM
3488be a string of commands accepted by the SQLi program. From the
3489output, the REGEXP is repeatedly matched and the list of
3490REGEXP-GROUPS submatches is returned. This behaves much like
3491\\[comint-redirect-results-list-from-process] but instead of
3492returning a single submatch it returns a list of each submatch
3493for each match."
3494
3495 (let ((outbuf " *SQL-Redirect-values*")
3496 (results nil))
fbcc67e2 3497 (sql-redirect sqlbuf command outbuf nil)
a386ac70
MM
3498 (with-current-buffer outbuf
3499 (while (re-search-forward regexp nil t)
3500 (push
3501 (cond
3502 ;; no groups-return all of them
3503 ((null regexp-groups)
fbcc67e2 3504 (let ((i (/ (length (match-data)) 2))
a386ac70 3505 (r nil))
fbcc67e2
MM
3506 (while (> i 0)
3507 (setq i (1- i))
a386ac70 3508 (push (match-string i) r))
fbcc67e2 3509 r))
a386ac70
MM
3510 ;; one group specified
3511 ((numberp regexp-groups)
3512 (match-string regexp-groups))
a386ac70
MM
3513 ;; list of numbers; return the specified matches only
3514 ((consp regexp-groups)
3515 (mapcar (lambda (c)
3516 (cond
3517 ((numberp c) (match-string c))
3518 ((stringp c) (match-substitute-replacement c))
3519 (t (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" c))))
3520 regexp-groups))
3521 ;; String is specified; return replacement string
3522 ((stringp regexp-groups)
3523 (match-substitute-replacement regexp-groups))
3524 (t
3525 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
3526 regexp-groups)))
3527 results)))
a386ac70 3528
fbcc67e2
MM
3529 (when sql-debug-redirect
3530 (message ">>SQL> = %S" (reverse results)))
3531
3532 (nreverse results)))
3533
3534(defun sql-execute (sqlbuf outbuf command enhanced arg)
3535 "Executes a command in a SQL interactive buffer and captures the output.
74790210
MM
3536
3537The commands are run in SQLBUF and the output saved in OUTBUF.
3538COMMAND must be a string, a function or a list of such elements.
3539Functions are called with SQLBUF, OUTBUF and ARG as parameters;
3540strings are formatted with ARG and executed.
3541
3542If the results are empty the OUTBUF is deleted, otherwise the
3543buffer is popped into a view window. "
3544 (mapc
3545 (lambda (c)
3546 (cond
3547 ((stringp c)
fbcc67e2 3548 (sql-redirect sqlbuf (if arg (format c arg) c) outbuf) t)
74790210 3549 ((functionp c)
fbcc67e2 3550 (apply c sqlbuf outbuf enhanced arg nil))
74790210
MM
3551 (t (error "Unknown sql-execute item %s" c))))
3552 (if (consp command) command (cons command nil)))
3553
3554 (setq outbuf (get-buffer outbuf))
3555 (if (zerop (buffer-size outbuf))
3556 (kill-buffer outbuf)
3557 (let ((one-win (eq (selected-window)
3558 (get-lru-window))))
3559 (with-current-buffer outbuf
3560 (set-buffer-modified-p nil)
bb5aa5d6 3561 (setq view-read-only t))
74790210
MM
3562 (view-buffer-other-window outbuf)
3563 (when one-win
3564 (shrink-window-if-larger-than-buffer)))))
3565
3566(defun sql-execute-feature (sqlbuf outbuf feature enhanced arg)
3567 "List objects or details in a separate display buffer."
3568 (let (command)
3569 (with-current-buffer sqlbuf
3570 (setq command (sql-get-product-feature sql-product feature)))
3571 (unless command
3572 (error "%s does not support %s" sql-product feature))
3573 (when (consp command)
3574 (setq command (if enhanced
3575 (cdr command)
3576 (car command))))
fbcc67e2
MM
3577 (sql-execute sqlbuf outbuf command enhanced arg)))
3578
3579(defvar sql-completion-object nil
3580 "A list of database objects used for completion.
3581
3582The list is maintained in SQL interactive buffers.")
3583
3584(defvar sql-completion-column nil
3585 "A list of column names used for completion.
3586
3587The list is maintained in SQL interactive buffers.")
3588
3589(defun sql-build-completions-1 (schema completion-list feature)
3590 "Generate a list of objects in the database for use as completions."
3591 (let ((f (sql-get-product-feature sql-product feature)))
3592 (when f
3593 (set completion-list
3594 (let (cl)
3595 (dolist (e (append (symbol-value completion-list)
3596 (apply f (current-buffer) (cons schema nil)))
3597 cl)
3598 (unless (member e cl) (setq cl (cons e cl))))
3599 (sort cl (function string<)))))))
3600
3601(defun sql-build-completions (schema)
3602 "Generate a list of names in the database for use as completions."
3603 (sql-build-completions-1 schema 'sql-completion-object :completion-object)
3604 (sql-build-completions-1 schema 'sql-completion-column :completion-column))
3605
3606(defvar sql-completion-sqlbuf nil)
3607
3608(defun sql-try-completion (string collection &optional predicate)
3609 (when sql-completion-sqlbuf
3610 (with-current-buffer sql-completion-sqlbuf
3611 (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string)
3612 (downcase (match-string 1 string)))))
3613
3614 ;; If we haven't loaded any object name yet, load local schema
3615 (unless sql-completion-object
3616 (sql-build-completions nil))
3617
3618 ;; If they want another schema, load it if we haven't yet
3619 (when schema
3620 (let ((schema-dot (concat schema "."))
3621 (schema-len (1+ (length schema)))
3622 (names sql-completion-object)
3623 has-schema)
3624
3625 (while (and (not has-schema) names)
3626 (setq has-schema (and
3627 (>= (length (car names)) schema-len)
3628 (string= schema-dot
91af3942 3629 (downcase (substring (car names)
fbcc67e2
MM
3630 0 schema-len))))
3631 names (cdr names)))
3632 (unless has-schema
3633 (sql-build-completions schema)))))
91af3942 3634
fbcc67e2
MM
3635 ;; Try to find the completion
3636 (cond
3637 ((not predicate)
3638 (try-completion string sql-completion-object))
3639 ((eq predicate t)
3640 (all-completions string sql-completion-object))
3641 ((eq predicate 'lambda)
3642 (test-completion string sql-completion-object))
3643 ((eq (car predicate) 'boundaries)
3644 (completion-boundaries string sql-completion-object nil (cdr predicate)))))))
74790210
MM
3645
3646(defun sql-read-table-name (prompt)
3647 "Read the name of a database table."
fbcc67e2
MM
3648 (let* ((tname
3649 (and (buffer-local-value 'sql-contains-names (current-buffer))
3650 (thing-at-point-looking-at
3651 (concat "\\_<\\sw\\(:?\\sw\\|\\s_\\)*"
3652 "\\(?:[.]+\\sw\\(?:\\sw\\|\\s_\\)*\\)*\\_>"))
3653 (buffer-substring-no-properties (match-beginning 0)
3654 (match-end 0))))
3655 (sql-completion-sqlbuf (sql-find-sqli-buffer))
3656 (product (with-current-buffer sql-completion-sqlbuf sql-product))
3657 (completion-ignore-case t))
3658
3659 (if (sql-get-product-feature product :completion-object)
3660 (completing-read prompt (function sql-try-completion)
3661 nil nil tname)
3662 (read-from-minibuffer prompt tname))))
74790210
MM
3663
3664(defun sql-list-all (&optional enhanced)
34e8a2da
GM
3665 "List all database objects.
3666With optional prefix argument ENHANCED, displays additional
3667details or extends the listing to include other schemas objects."
74790210
MM
3668 (interactive "P")
3669 (let ((sqlbuf (sql-find-sqli-buffer)))
3670 (unless sqlbuf
3671 (error "No SQL interactive buffer found"))
fbcc67e2
MM
3672 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil)
3673 (with-current-buffer sqlbuf
3674 ;; Contains the name of database objects
3675 (set (make-local-variable 'sql-contains-names) t)
3676 (set (make-local-variable 'sql-buffer) sqlbuf))))
74790210
MM
3677
3678(defun sql-list-table (name &optional enhanced)
34e8a2da
GM
3679 "List the details of a database table named NAME.
3680Displays the columns in the relation. With optional prefix argument
3681ENHANCED, displays additional details about each column."
74790210
MM
3682 (interactive
3683 (list (sql-read-table-name "Table name: ")
3684 current-prefix-arg))
3685 (let ((sqlbuf (sql-find-sqli-buffer)))
3686 (unless sqlbuf
3687 (error "No SQL interactive buffer found"))
3688 (unless name
3689 (error "No table name specified"))
3690 (sql-execute-feature sqlbuf (format "*List %s*" name)
3691 :list-table enhanced name)))
a386ac70
MM
3692\f
3693
95e4b2ef
RS
3694;;; SQL mode -- uses SQL interactive mode
3695
3696;;;###autoload
175069ef 3697(define-derived-mode sql-mode prog-mode "SQL"
95e4b2ef
RS
3698 "Major mode to edit SQL.
3699
dab100d7 3700You can send SQL statements to the SQLi buffer using
95e4b2ef 3701\\[sql-send-region]. Such a buffer must exist before you can do this.
dab100d7 3702See `sql-help' on how to create SQLi buffers.
95e4b2ef 3703
801d1cb0 3704\\{sql-mode-map}
95e4b2ef
RS
3705Customization: Entry to this mode runs the `sql-mode-hook'.
3706
dab100d7
RS
3707When you put a buffer in SQL mode, the buffer stores the last SQLi
3708buffer created as its destination in the variable `sql-buffer'. This
3709will be the buffer \\[sql-send-region] sends the region to. If this
3710SQLi buffer is killed, \\[sql-send-region] is no longer able to
c7055d66
RS
3711determine where the strings should be sent to. You can set the
3712value of `sql-buffer' using \\[sql-set-sqli-buffer].
95e4b2ef 3713
dab100d7 3714For information on how to create multiple SQLi buffers, see
4da8ff79
RS
3715`sql-interactive-mode'.
3716
3717Note that SQL doesn't have an escape character unless you specify
3718one. If you specify backslash as escape character in SQL,
3719you must tell Emacs. Here's how to do that in your `~/.emacs' file:
3720
3721\(add-hook 'sql-mode-hook
3722 (lambda ()
3723 (modify-syntax-entry ?\\\\ \".\" sql-mode-syntax-table)))"
175069ef 3724 :abbrev-table sql-mode-abbrev-table
311e7a89
GM
3725 (if sql-mode-menu
3726 (easy-menu-add sql-mode-menu)); XEmacs
0d327994 3727
175069ef 3728 (set (make-local-variable 'comment-start) "--")
801d1cb0 3729 ;; Make each buffer in sql-mode remember the "current" SQLi buffer.
dab100d7 3730 (make-local-variable 'sql-buffer)
801d1cb0
AS
3731 ;; Add imenu support for sql-mode. Note that imenu-generic-expression
3732 ;; is buffer-local, so we don't need a local-variable for it. SQL is
3733 ;; case-insensitive, that's why we have to set imenu-case-fold-search.
801d1cb0 3734 (setq imenu-generic-expression sql-imenu-generic-expression
78024f88 3735 imenu-case-fold-search t)
c7055d66
RS
3736 ;; Make `sql-send-paragraph' work on paragraphs that contain indented
3737 ;; lines.
175069ef
SM
3738 (set (make-local-variable 'paragraph-separate) "[\f]*$")
3739 (set (make-local-variable 'paragraph-start) "[\n\f]")
801d1cb0 3740 ;; Abbrevs
95e4b2ef 3741 (setq abbrev-all-caps 1)
fbcc67e2
MM
3742 ;; Contains the name of database objects
3743 (set (make-local-variable 'sql-contains-names) t)
78024f88 3744 ;; Catch changes to sql-product and highlight accordingly
78024f88 3745 (add-hook 'hack-local-variables-hook 'sql-highlight-product t t))
95e4b2ef
RS
3746
3747\f
3748
3749;;; SQL interactive mode
3750
3751(put 'sql-interactive-mode 'mode-class 'special)
3752
3753(defun sql-interactive-mode ()
3754 "Major mode to use a SQL interpreter interactively.
3755
3756Do not call this function by yourself. The environment must be
063c6324
JB
3757initialized by an entry function specific for the SQL interpreter.
3758See `sql-help' for a list of available entry functions.
95e4b2ef
RS
3759
3760\\[comint-send-input] after the end of the process' output sends the
3761text from the end of process to the end of the current line.
3762\\[comint-send-input] before end of process output copies the current
3763line minus the prompt to the end of the buffer and sends it.
3764\\[comint-copy-old-input] just copies the current line.
3765Use \\[sql-accumulate-and-indent] to enter multi-line statements.
3766
3767If you want to make multiple SQL buffers, rename the `*SQL*' buffer
3768using \\[rename-buffer] or \\[rename-uniquely] and start a new process.
dab100d7
RS
3769See `sql-help' for a list of available entry functions. The last buffer
3770created by such an entry function is the current SQLi buffer. SQL
3771buffers will send strings to the SQLi buffer current at the time of
3772their creation. See `sql-mode' for details.
3773
3774Sample session using two connections:
3775
37761. Create first SQLi buffer by calling an entry function.
37772. Rename buffer \"*SQL*\" to \"*Connection 1*\".
37783. Create a SQL buffer \"test1.sql\".
37794. Create second SQLi buffer by calling an entry function.
37805. Rename buffer \"*SQL*\" to \"*Connection 2*\".
37816. Create a SQL buffer \"test2.sql\".
3782
3783Now \\[sql-send-region] in buffer \"test1.sql\" will send the region to
3784buffer \"*Connection 1*\", \\[sql-send-region] in buffer \"test2.sql\"
3785will send the region to buffer \"*Connection 2*\".
95e4b2ef
RS
3786
3787If you accidentally suspend your process, use \\[comint-continue-subjob]
dab100d7
RS
3788to continue it. On some operating systems, this will not work because
3789the signals are not supported.
95e4b2ef
RS
3790
3791\\{sql-interactive-mode-map}
3792Customization: Entry to this mode runs the hooks on `comint-mode-hook'
3793and `sql-interactive-mode-hook' (in that order). Before each input, the
3794hooks on `comint-input-filter-functions' are run. After each SQL
3795interpreter output, the hooks on `comint-output-filter-functions' are
3796run.
3797
280412d8 3798Variable `sql-input-ring-file-name' controls the initialization of the
77d352a6 3799input ring history.
95e4b2ef
RS
3800
3801Variables `comint-output-filter-functions', a hook, and
3802`comint-scroll-to-bottom-on-input' and
3803`comint-scroll-to-bottom-on-output' control whether input and output
3804cause the window to scroll to the end of the buffer.
3805
3806If you want to make SQL buffers limited in length, add the function
3807`comint-truncate-buffer' to `comint-output-filter-functions'.
3808
dab100d7 3809Here is an example for your .emacs file. It keeps the SQLi buffer a
c7055d66 3810certain length.
95e4b2ef
RS
3811
3812\(add-hook 'sql-interactive-mode-hook
3813 \(function (lambda ()
95e4b2ef
RS
3814 \(setq comint-output-filter-functions 'comint-truncate-buffer))))
3815
3816Here is another example. It will always put point back to the statement
3817you entered, right above the output it created.
3818
801d1cb0 3819\(setq comint-output-filter-functions
95e4b2ef 3820 \(function (lambda (STR) (comint-show-output))))"
03789b21 3821 (delay-mode-hooks (comint-mode))
7492acc9 3822
78024f88
AS
3823 ;; Get the `sql-product' for this interactive session.
3824 (set (make-local-variable 'sql-product)
3825 (or sql-interactive-product
3826 sql-product))
7492acc9 3827
78024f88 3828 ;; Setup the mode.
fbcc67e2 3829 (setq major-mode 'sql-interactive-mode)
175069ef
SM
3830 (setq mode-name
3831 (concat "SQLi[" (or (sql-get-product-feature sql-product :name)
3832 (symbol-name sql-product)) "]"))
95e4b2ef 3833 (use-local-map sql-interactive-mode-map)
311e7a89 3834 (if sql-interactive-mode-menu
78024f88 3835 (easy-menu-add sql-interactive-mode-menu)) ; XEmacs
95e4b2ef 3836 (set-syntax-table sql-mode-syntax-table)
7492acc9 3837
a081a529 3838 ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
801d1cb0 3839 ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
e4769531 3840 ;; will have just one quote. Therefore syntactic highlighting is
78024f88
AS
3841 ;; disabled for interactive buffers. No imenu support.
3842 (sql-product-font-lock t nil)
7492acc9 3843
c7055d66 3844 ;; Enable commenting and uncommenting of the region.
175069ef 3845 (set (make-local-variable 'comment-start) "--")
78024f88 3846 ;; Abbreviation table init and case-insensitive. It is not activated
c7055d66 3847 ;; by default.
95e4b2ef
RS
3848 (setq local-abbrev-table sql-mode-abbrev-table)
3849 (setq abbrev-all-caps 1)
c7055d66 3850 ;; Exiting the process will call sql-stop.
9250002f 3851 (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop)
fbcc67e2
MM
3852 ;; Save the connection and login params
3853 (set (make-local-variable 'sql-user) sql-user)
3854 (set (make-local-variable 'sql-database) sql-database)
3855 (set (make-local-variable 'sql-server) sql-server)
3856 (set (make-local-variable 'sql-port) sql-port)
3857 (set (make-local-variable 'sql-connection) sql-connection)
f6561e1f 3858 (setq-default sql-connection nil)
fbcc67e2
MM
3859 ;; Contains the name of database objects
3860 (set (make-local-variable 'sql-contains-names) t)
3861 ;; Keep track of existing object names
3862 (set (make-local-variable 'sql-completion-object) nil)
3863 (set (make-local-variable 'sql-completion-column) nil)
3864 ;; Create a useful name for renaming this buffer later.
175069ef
SM
3865 (set (make-local-variable 'sql-alternate-buffer-name)
3866 (sql-make-alternate-buffer-name))
78024f88
AS
3867 ;; User stuff. Initialize before the hook.
3868 (set (make-local-variable 'sql-prompt-regexp)
7492acc9 3869 (sql-get-product-feature sql-product :prompt-regexp))
78024f88 3870 (set (make-local-variable 'sql-prompt-length)
7492acc9 3871 (sql-get-product-feature sql-product :prompt-length))
3bd2cfef
MM
3872 (set (make-local-variable 'sql-prompt-cont-regexp)
3873 (sql-get-product-feature sql-product :prompt-cont-regexp))
3874 (make-local-variable 'sql-output-newline-count)
fbcc67e2 3875 (make-local-variable 'sql-preoutput-hold)
3bd2cfef
MM
3876 (make-local-variable 'sql-output-by-send)
3877 (add-hook 'comint-preoutput-filter-functions
3878 'sql-interactive-remove-continuation-prompt nil t)
78024f88
AS
3879 (make-local-variable 'sql-input-ring-separator)
3880 (make-local-variable 'sql-input-ring-file-name)
7492acc9 3881 ;; Run the mode hook (along with comint's hooks).
9a969196 3882 (run-mode-hooks 'sql-interactive-mode-hook)
78024f88 3883 ;; Set comint based on user overrides.
3bd2cfef
MM
3884 (setq comint-prompt-regexp
3885 (if sql-prompt-cont-regexp
3886 (concat "\\(" sql-prompt-regexp
3887 "\\|" sql-prompt-cont-regexp "\\)")
3888 sql-prompt-regexp))
78024f88 3889 (setq left-margin sql-prompt-length)
7492acc9
MM
3890 ;; Install input sender
3891 (set (make-local-variable 'comint-input-sender) 'sql-input-sender)
77d352a6
GM
3892 ;; People wanting a different history file for each
3893 ;; buffer/process/client/whatever can change separator and file-name
3894 ;; on the sql-interactive-mode-hook.
3895 (setq comint-input-ring-separator sql-input-ring-separator
3896 comint-input-ring-file-name sql-input-ring-file-name)
c7055d66 3897 ;; Calling the hook before calling comint-read-input-ring allows users
95e4b2ef 3898 ;; to set comint-input-ring-file-name in sql-interactive-mode-hook.
77d352a6 3899 (comint-read-input-ring t))
95e4b2ef
RS
3900
3901(defun sql-stop (process event)
3902 "Called when the SQL process is stopped.
3903
c7055d66
RS
3904Writes the input history to a history file using
3905`comint-write-input-ring' and inserts a short message in the SQL buffer.
95e4b2ef
RS
3906
3907This function is a sentinel watching the SQL interpreter process.
3908Sentinels will always get the two parameters PROCESS and EVENT."
77d352a6
GM
3909 (comint-write-input-ring)
3910 (if (and (eq (current-buffer) sql-buffer)
3911 (not buffer-read-only))
3912 (insert (format "\nProcess %s %s\n" process event))
3913 (message "Process %s %s" process event)))
95e4b2ef
RS
3914
3915\f
3916
5474c40f 3917;;; Connection handling
30c4d8dc 3918
74790210
MM
3919(defun sql-read-connection (prompt &optional initial default)
3920 "Read a connection name."
3921 (let ((completion-ignore-case t))
3922 (completing-read prompt
3923 (mapcar (lambda (c) (car c))
3924 sql-connection-alist)
3925 nil t initial 'sql-connection-history default)))
3926
30c4d8dc 3927;;;###autoload
fbcc67e2 3928(defun sql-connect (connection &optional new-name)
30c4d8dc
MM
3929 "Connect to an interactive session using CONNECTION settings.
3930
3931See `sql-connection-alist' to see how to define connections and
3932their settings.
3933
3934The user will not be prompted for any login parameters if a value
3935is specified in the connection settings."
3936
3937 ;; Prompt for the connection from those defined in the alist
3938 (interactive
3939 (if sql-connection-alist
fbcc67e2
MM
3940 (list (sql-read-connection "Connection: " nil '(nil))
3941 current-prefix-arg)
30c4d8dc
MM
3942 nil))
3943
3944 ;; Are there connections defined
3945 (if sql-connection-alist
3946 ;; Was one selected
3947 (when connection
3948 ;; Get connection settings
d26b0ea9 3949 (let ((connect-set (assoc connection sql-connection-alist)))
30c4d8dc
MM
3950 ;; Settings are defined
3951 (if connect-set
3952 ;; Set the desired parameters
f6561e1f
MM
3953 (let (param-var login-params set-params rem-params)
3954
3955 ;; :sqli-login params variable
3956 (setq param-var
3957 (sql-get-product-feature sql-product :sqli-login nil t))
3958
3959 ;; :sqli-login params value
3960 (setq login-params
3961 (sql-get-product-feature sql-product :sqli-login))
3962
3963 ;; Params in the connection
3964 (setq set-params
3965 (mapcar
3966 (lambda (v)
3967 (cond
3968 ((eq (car v) 'sql-user) 'user)
3969 ((eq (car v) 'sql-password) 'password)
3970 ((eq (car v) 'sql-server) 'server)
3971 ((eq (car v) 'sql-database) 'database)
3972 ((eq (car v) 'sql-port) 'port)
3973 (t (car v))))
3974 (cdr connect-set)))
3975
3976 ;; the remaining params (w/o the connection params)
3977 (setq rem-params
3978 (sql-for-each-login login-params
3979 (lambda (token plist)
3980 (unless (member token set-params)
3981 (if plist (cons token plist) token)))))
3982
3983 ;; Set the parameters and start the interactive session
3984 (mapc
3985 (lambda (vv)
3986 (set-default (car vv) (eval (cadr vv))))
3987 (cdr connect-set))
3988 (setq-default sql-connection connection)
3989
3990 ;; Start the SQLi session with revised list of login parameters
3991 (eval `(let ((,param-var ',rem-params))
3992 (sql-product-interactive sql-product new-name))))
fbcc67e2 3993
d26b0ea9 3994 (message "SQL Connection <%s> does not exist" connection)
30c4d8dc 3995 nil)))
f6561e1f 3996
30c4d8dc
MM
3997 (message "No SQL Connections defined")
3998 nil))
78024f88 3999
d26b0ea9
MM
4000(defun sql-save-connection (name)
4001 "Captures the connection information of the current SQLi session.
4002
4003The information is appended to `sql-connection-alist' and
4004optionally is saved to the user's init file."
4005
4006 (interactive "sNew connection name: ")
4007
fbcc67e2
MM
4008 (unless (derived-mode-p 'sql-interactive-mode)
4009 (error "Not in a SQL interactive mode!"))
4010
4011 ;; Capture the buffer local settings
4012 (let* ((buf (current-buffer))
4013 (connection (buffer-local-value 'sql-connection buf))
4014 (product (buffer-local-value 'sql-product buf))
4015 (user (buffer-local-value 'sql-user buf))
4016 (database (buffer-local-value 'sql-database buf))
4017 (server (buffer-local-value 'sql-server buf))
4018 (port (buffer-local-value 'sql-port buf)))
4019
4020 (if connection
4021 (message "This session was started by a connection; it's already been saved.")
91af3942 4022
fbcc67e2
MM
4023 (let ((login (sql-get-product-feature product :sqli-login))
4024 (alist sql-connection-alist)
4025 connect)
91af3942 4026
fbcc67e2
MM
4027 ;; Remove the existing connection if the user says so
4028 (when (and (assoc name alist)
4029 (yes-or-no-p (format "Replace connection definition <%s>? " name)))
4030 (setq alist (assq-delete-all name alist)))
91af3942 4031
fbcc67e2
MM
4032 ;; Add the new connection if it doesn't exist
4033 (if (assoc name alist)
4034 (message "Connection <%s> already exists" name)
4035 (setq connect
4036 (append (list name)
4037 (sql-for-each-login
4038 `(product ,@login)
4039 (lambda (token _plist)
4040 (cond
4041 ((eq token 'product) `(sql-product ',product))
4042 ((eq token 'user) `(sql-user ,user))
4043 ((eq token 'database) `(sql-database ,database))
4044 ((eq token 'server) `(sql-server ,server))
4045 ((eq token 'port) `(sql-port ,port)))))))
4046
4047 (setq alist (append alist (list connect)))
4048
4049 ;; confirm whether we want to save the connections
4050 (if (yes-or-no-p "Save the connections for future sessions? ")
4051 (customize-save-variable 'sql-connection-alist alist)
4052 (customize-set-variable 'sql-connection-alist alist)))))))
d26b0ea9
MM
4053
4054(defun sql-connection-menu-filter (tail)
4055 "Generates menu entries for using each connection."
4056 (append
4057 (mapcar
4058 (lambda (conn)
4059 (vector
fbcc67e2
MM
4060 (format "Connection <%s>\t%s" (car conn)
4061 (let ((sql-user "") (sql-database "")
4062 (sql-server "") (sql-port 0))
4063 (eval `(let ,(cdr conn) (sql-make-alternate-buffer-name)))))
d26b0ea9
MM
4064 (list 'sql-connect (car conn))
4065 t))
4066 sql-connection-alist)
4067 tail))
4068
5474c40f
MM
4069\f
4070
4071;;; Entry functions for different SQL interpreters.
4072
4073;;;###autoload
9250002f 4074(defun sql-product-interactive (&optional product new-name)
5474c40f
MM
4075 "Run PRODUCT interpreter as an inferior process.
4076
4077If buffer `*SQL*' exists but no process is running, make a new process.
4078If buffer exists and a process is running, just switch to buffer `*SQL*'.
4079
9250002f
MM
4080To specify the SQL product, prefix the call with
4081\\[universal-argument]. To set the buffer name as well, prefix
4082the call to \\[sql-product-interactive] with
4083\\[universal-argument] \\[universal-argument].
4084
5474c40f
MM
4085\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
4086 (interactive "P")
4087
9250002f
MM
4088 ;; Handle universal arguments if specified
4089 (when (not (or executing-kbd-macro noninteractive))
a386ac70 4090 (when (and (consp product)
9250002f
MM
4091 (not (cdr product))
4092 (numberp (car product)))
74790210 4093 (when (>= (prefix-numeric-value product) 16)
9250002f
MM
4094 (when (not new-name)
4095 (setq new-name '(4)))
4096 (setq product '(4)))))
4097
4098 ;; Get the value of product that we need
5474c40f
MM
4099 (setq product
4100 (cond
74790210
MM
4101 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product
4102 (sql-read-product "SQL product: " sql-product))
fbcc67e2
MM
4103 ((and product ; Product specified
4104 (symbolp product)) product)
5474c40f
MM
4105 (t sql-product))) ; Default to sql-product
4106
9250002f 4107 ;; If we have a product and it has a interactive mode
5474c40f
MM
4108 (if product
4109 (when (sql-get-product-feature product :sqli-comint-func)
74790210
MM
4110 ;; If no new name specified, try to pop to an active SQL
4111 ;; interactive for the same product
fbcc67e2 4112 (let ((buf (sql-find-sqli-buffer product sql-connection)))
74790210
MM
4113 (if (and (not new-name) buf)
4114 (pop-to-buffer buf)
4115
4116 ;; We have a new name or sql-buffer doesn't exist or match
4117 ;; Start by remembering where we start
4118 (let ((start-buffer (current-buffer))
4119 new-sqli-buffer)
4120
4121 ;; Get credentials.
4122 (apply 'sql-get-login (sql-get-product-feature product :sqli-login))
4123
4124 ;; Connect to database.
4125 (message "Login...")
f6561e1f
MM
4126 (let ((sql-user (default-value 'sql-user))
4127 (sql-password (default-value 'sql-password))
4128 (sql-server (default-value 'sql-server))
4129 (sql-database (default-value 'sql-database))
4130 (sql-port (default-value 'sql-port)))
4131 (funcall (sql-get-product-feature product :sqli-comint-func)
4132 product
4133 (sql-get-product-feature product :sqli-options)))
74790210
MM
4134
4135 ;; Set SQLi mode.
74790210
MM
4136 (let ((sql-interactive-product product))
4137 (sql-interactive-mode))
4138
4139 ;; Set the new buffer name
fbcc67e2 4140 (setq new-sqli-buffer (current-buffer))
74790210
MM
4141 (when new-name
4142 (sql-rename-buffer new-name))
f6561e1f 4143 (set (make-local-variable 'sql-buffer)
bb5aa5d6 4144 (buffer-name new-sqli-buffer))
fbcc67e2
MM
4145
4146 ;; Set `sql-buffer' in the start buffer
74790210 4147 (with-current-buffer start-buffer
fbcc67e2
MM
4148 (when (derived-mode-p 'sql-mode)
4149 (setq sql-buffer (buffer-name new-sqli-buffer))
4150 (run-hooks 'sql-set-sqli-hook)))
5474c40f 4151
74790210
MM
4152 ;; All done.
4153 (message "Login...done")
bb5aa5d6 4154 (run-hooks 'sql-login-hook)
fbcc67e2 4155 (pop-to-buffer new-sqli-buffer)))))
5474c40f
MM
4156 (message "No default SQL product defined. Set `sql-product'.")))
4157
4158(defun sql-comint (product params)
4159 "Set up a comint buffer to run the SQL processor.
4160
4161PRODUCT is the SQL product. PARAMS is a list of strings which are
4162passed as command line arguments."
9250002f
MM
4163 (let ((program (sql-get-product-feature product :sqli-program))
4164 (buf-name "SQL"))
2bb1ae55
MA
4165 ;; Make sure we can find the program. `executable-find' does not
4166 ;; work for remote hosts; we suppress the check there.
4167 (unless (or (file-remote-p default-directory)
4168 (executable-find program))
74790210 4169 (error "Unable to locate SQL program \'%s\'" program))
2bb1ae55 4170 ;; Make sure buffer name is unique.
74790210 4171 (when (sql-buffer-live-p (format "*%s*" buf-name))
9250002f 4172 (setq buf-name (format "SQL-%s" product))
74790210 4173 (when (sql-buffer-live-p (format "*%s*" buf-name))
9250002f 4174 (let ((i 1))
74790210
MM
4175 (while (sql-buffer-live-p
4176 (format "*%s*"
4177 (setq buf-name (format "SQL-%s%d" product i))))
9250002f 4178 (setq i (1+ i))))))
5474c40f 4179 (set-buffer
9250002f 4180 (apply 'make-comint buf-name program nil params))))
5474c40f 4181
77d352a6 4182;;;###autoload
9250002f 4183(defun sql-oracle (&optional buffer)
95e4b2ef
RS
4184 "Run sqlplus by Oracle as an inferior process.
4185
dab100d7 4186If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4187If buffer exists and a process is running, just switch to buffer
4188`*SQL*'.
4189
dab100d7
RS
4190Interpreter used comes from variable `sql-oracle-program'. Login uses
4191the variables `sql-user', `sql-password', and `sql-database' as
9ef3882f
GM
4192defaults, if set. Additional command line parameters can be stored in
4193the list `sql-oracle-options'.
95e4b2ef 4194
063c6324 4195The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4196input. See `sql-interactive-mode'.
4197
9250002f
MM
4198To set the buffer name directly, use \\[universal-argument]
4199before \\[sql-oracle]. Once session has started,
4200\\[sql-rename-buffer] can be called separately to rename the
4201buffer.
4202
95e4b2ef
RS
4203To specify a coding system for converting non-ASCII characters
4204in the input and output to the process, use \\[universal-coding-system-argument]
4205before \\[sql-oracle]. You can also specify this with \\[set-buffer-process-coding-system]
4206in the SQL buffer, after you start the process.
4207The default comes from `process-coding-system-alist' and
4208`default-process-coding-system'.
4209
4210\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4211 (interactive "P")
4212 (sql-product-interactive 'oracle buffer))
78024f88 4213
30c4d8dc 4214(defun sql-comint-oracle (product options)
7492acc9 4215 "Create comint buffer and connect to Oracle."
78024f88
AS
4216 ;; Produce user/password@database construct. Password without user
4217 ;; is meaningless; database without user/password is meaningless,
4218 ;; because "@param" will ask sqlplus to interpret the script
4219 ;; "param".
7492acc9
MM
4220 (let ((parameter nil))
4221 (if (not (string= "" sql-user))
4222 (if (not (string= "" sql-password))
4223 (setq parameter (concat sql-user "/" sql-password))
4224 (setq parameter sql-user)))
78024f88
AS
4225 (if (and parameter (not (string= "" sql-database)))
4226 (setq parameter (concat parameter "@" sql-database)))
7492acc9
MM
4227 (if parameter
4228 (setq parameter (nconc (list parameter) options))
4229 (setq parameter options))
30c4d8dc 4230 (sql-comint product parameter)))
95e4b2ef 4231
fbcc67e2
MM
4232(defun sql-oracle-save-settings (sqlbuf)
4233 "Saves most SQL*Plus settings so they may be reset by \\[sql-redirect]."
4234 ;; Note: does not capture the following settings:
4235 ;;
4236 ;; APPINFO
4237 ;; BTITLE
4238 ;; COMPATIBILITY
4239 ;; COPYTYPECHECK
4240 ;; MARKUP
4241 ;; RELEASE
4242 ;; REPFOOTER
4243 ;; REPHEADER
4244 ;; SQLPLUSCOMPATIBILITY
4245 ;; TTITLE
4246 ;; USER
4247 ;;
4248
4249 (append
4250 ;; (apply 'concat (append
4251 ;; '("SET")
4252
4253 ;; option value...
4254 (sql-redirect-value
4255 sqlbuf
4256 (concat "SHOW ARRAYSIZE AUTOCOMMIT AUTOPRINT AUTORECOVERY AUTOTRACE"
4257 " CMDSEP COLSEP COPYCOMMIT DESCRIBE ECHO EDITFILE EMBEDDED"
4258 " ESCAPE FLAGGER FLUSH HEADING INSTANCE LINESIZE LNO LOBOFFSET"
4259 " LOGSOURCE LONG LONGCHUNKSIZE NEWPAGE NULL NUMFORMAT NUMWIDTH"
4260 " PAGESIZE PAUSE PNO RECSEP SERVEROUTPUT SHIFTINOUT SHOWMODE"
4261 " SPOOL SQLBLANKLINES SQLCASE SQLCODE SQLCONTINUE SQLNUMBER"
4262 " SQLPROMPT SUFFIX TAB TERMOUT TIMING TRIMOUT TRIMSPOOL VERIFY")
4263 "^.+$"
4264 "SET \\&")
4265
4266 ;; option "c" (hex xx)
4267 (sql-redirect-value
4268 sqlbuf
4269 (concat "SHOW BLOCKTERMINATOR CONCAT DEFINE SQLPREFIX SQLTERMINATOR"
4270 " UNDERLINE HEADSEP RECSEPCHAR")
4271 "^\\(.+\\) (hex ..)$"
4272 "SET \\1")
4273
99d99081 4274 ;; FEEDBACK ON for 99 or more rows
fbcc67e2
MM
4275 ;; feedback OFF
4276 (sql-redirect-value
4277 sqlbuf
4278 "SHOW FEEDBACK"
4279 "^\\(?:FEEDBACK ON for \\([[:digit:]]+\\) or more rows\\|feedback \\(OFF\\)\\)"
4280 "SET FEEDBACK \\1\\2")
4281
4282 ;; wrap : lines will be wrapped
4283 ;; wrap : lines will be truncated
4284 (list (concat "SET WRAP "
4285 (if (string=
4286 (car (sql-redirect-value
4287 sqlbuf
4288 "SHOW WRAP"
4289 "^wrap : lines will be \\(wrapped\\|truncated\\)" 1))
4290 "wrapped")
4291 "ON" "OFF")))))
4292
4293(defun sql-oracle-restore-settings (sqlbuf saved-settings)
4294 "Restore the SQL*Plus settings in SAVED-SETTINGS."
4295
4296 ;; Remove any settings that haven't changed
4297 (mapc
4298 (lambda (one-cur-setting)
4299 (setq saved-settings (delete one-cur-setting saved-settings)))
4300 (sql-oracle-save-settings sqlbuf))
4301
4302 ;; Restore the changed settings
4303 (sql-redirect sqlbuf saved-settings))
4304
4305(defun sql-oracle-list-all (sqlbuf outbuf enhanced table-name)
4306 ;; Query from USER_OBJECTS or ALL_OBJECTS
4307 (let ((settings (sql-oracle-save-settings sqlbuf))
4308 (simple-sql
4309 (concat
4310 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4311 ", x.object_name AS SQL_EL_NAME "
4312 "FROM user_objects x "
4313 "WHERE x.object_type NOT LIKE '%% BODY' "
4314 "ORDER BY 2, 1;"))
4315 (enhanced-sql
4316 (concat
4317 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4318 ", x.owner ||'.'|| x.object_name AS SQL_EL_NAME "
4319 "FROM all_objects x "
4320 "WHERE x.object_type NOT LIKE '%% BODY' "
4321 "AND x.owner <> 'SYS' "
4322 "ORDER BY 2, 1;")))
4323
4324 (sql-redirect sqlbuf
4325 (concat "SET LINESIZE 80 PAGESIZE 50000 TRIMOUT ON"
4326 " TAB OFF TIMING OFF FEEDBACK OFF"))
4327
4328 (sql-redirect sqlbuf
4329 (list "COLUMN SQL_EL_TYPE HEADING \"Type\" FORMAT A19"
4330 "COLUMN SQL_EL_NAME HEADING \"Name\""
4331 (format "COLUMN SQL_EL_NAME FORMAT A%d"
4332 (if enhanced 60 35))))
4333
4334 (sql-redirect sqlbuf
4335 (if enhanced enhanced-sql simple-sql)
4336 outbuf)
4337
4338 (sql-redirect sqlbuf
4339 '("COLUMN SQL_EL_NAME CLEAR"
4340 "COLUMN SQL_EL_TYPE CLEAR"))
4341
4342 (sql-oracle-restore-settings sqlbuf settings)))
4343
4344(defun sql-oracle-list-table (sqlbuf outbuf enhanced table-name)
4345 "Implements :list-table under Oracle."
4346 (let ((settings (sql-oracle-save-settings sqlbuf)))
4347
4348 (sql-redirect sqlbuf
4349 (format
4350 (concat "SET LINESIZE %d PAGESIZE 50000"
4351 " DESCRIBE DEPTH 1 LINENUM OFF INDENT ON")
4352 (max 65 (min 120 (window-width)))))
4353
4354 (sql-redirect sqlbuf (format "DESCRIBE %s" table-name)
4355 outbuf)
4356
4357 (sql-oracle-restore-settings sqlbuf settings)))
4358
4359(defcustom sql-oracle-completion-types '("FUNCTION" "PACKAGE" "PROCEDURE"
4360 "SEQUENCE" "SYNONYM" "TABLE" "TRIGGER"
4361 "TYPE" "VIEW")
4362 "List of object types to include for completion under Oracle.
4363
4364See the distinct values in ALL_OBJECTS.OBJECT_TYPE for possible values."
4365 :version "24.1"
4366 :type '(repeat string)
4367 :group 'SQL)
4368
4369(defun sql-oracle-completion-object (sqlbuf schema)
4370 (sql-redirect-value
4371 sqlbuf
4372 (concat
4373 "SELECT CHR(1)||"
4374 (if schema
4375 (format "owner||'.'||object_name AS o FROM all_objects WHERE owner = %s AND "
4376 (sql-str-literal (upcase schema)))
4377 "object_name AS o FROM user_objects WHERE ")
4378 "temporary = 'N' AND generated = 'N' AND secondary = 'N' AND "
4379 "object_type IN ("
4380 (mapconcat (function sql-str-literal) sql-oracle-completion-types ",")
4381 ");")
4382 "^[\001]\\(.+\\)$" 1))
95e4b2ef
RS
4383\f
4384
77d352a6 4385;;;###autoload
9250002f 4386(defun sql-sybase (&optional buffer)
c38762fd 4387 "Run isql by Sybase as an inferior process.
95e4b2ef 4388
dab100d7 4389If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4390If buffer exists and a process is running, just switch to buffer
4391`*SQL*'.
4392
4393Interpreter used comes from variable `sql-sybase-program'. Login uses
9b5360aa 4394the variables `sql-server', `sql-user', `sql-password', and
7a65c85c
GM
4395`sql-database' as defaults, if set. Additional command line parameters
4396can be stored in the list `sql-sybase-options'.
95e4b2ef 4397
063c6324 4398The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4399input. See `sql-interactive-mode'.
4400
9250002f
MM
4401To set the buffer name directly, use \\[universal-argument]
4402before \\[sql-sybase]. Once session has started,
4403\\[sql-rename-buffer] can be called separately to rename the
4404buffer.
4405
95e4b2ef
RS
4406To specify a coding system for converting non-ASCII characters
4407in the input and output to the process, use \\[universal-coding-system-argument]
4408before \\[sql-sybase]. You can also specify this with \\[set-buffer-process-coding-system]
4409in the SQL buffer, after you start the process.
4410The default comes from `process-coding-system-alist' and
4411`default-process-coding-system'.
4412
4413\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4414 (interactive "P")
4415 (sql-product-interactive 'sybase buffer))
78024f88 4416
30c4d8dc 4417(defun sql-comint-sybase (product options)
7492acc9 4418 "Create comint buffer and connect to Sybase."
78024f88
AS
4419 ;; Put all parameters to the program (if defined) in a list and call
4420 ;; make-comint.
7492acc9 4421 (let ((params options))
78024f88
AS
4422 (if (not (string= "" sql-server))
4423 (setq params (append (list "-S" sql-server) params)))
4424 (if (not (string= "" sql-database))
4425 (setq params (append (list "-D" sql-database) params)))
4426 (if (not (string= "" sql-password))
4427 (setq params (append (list "-P" sql-password) params)))
4428 (if (not (string= "" sql-user))
4429 (setq params (append (list "-U" sql-user) params)))
30c4d8dc 4430 (sql-comint product params)))
95e4b2ef
RS
4431
4432\f
4433
77d352a6 4434;;;###autoload
9250002f 4435(defun sql-informix (&optional buffer)
95e4b2ef
RS
4436 "Run dbaccess by Informix as an inferior process.
4437
dab100d7 4438If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4439If buffer exists and a process is running, just switch to buffer
4440`*SQL*'.
4441
4442Interpreter used comes from variable `sql-informix-program'. Login uses
4443the variable `sql-database' as default, if set.
4444
063c6324 4445The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4446input. See `sql-interactive-mode'.
4447
9250002f
MM
4448To set the buffer name directly, use \\[universal-argument]
4449before \\[sql-informix]. Once session has started,
4450\\[sql-rename-buffer] can be called separately to rename the
4451buffer.
4452
95e4b2ef
RS
4453To specify a coding system for converting non-ASCII characters
4454in the input and output to the process, use \\[universal-coding-system-argument]
4455before \\[sql-informix]. You can also specify this with \\[set-buffer-process-coding-system]
4456in the SQL buffer, after you start the process.
4457The default comes from `process-coding-system-alist' and
4458`default-process-coding-system'.
4459
4460\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4461 (interactive "P")
4462 (sql-product-interactive 'informix buffer))
78024f88 4463
30c4d8dc 4464(defun sql-comint-informix (product options)
7492acc9 4465 "Create comint buffer and connect to Informix."
78024f88 4466 ;; username and password are ignored.
7492acc9
MM
4467 (let ((db (if (string= "" sql-database)
4468 "-"
4469 (if (string= "" sql-server)
4470 sql-database
4471 (concat sql-database "@" sql-server)))))
30c4d8dc 4472 (sql-comint product (append `(,db "-") options))))
a081a529
RS
4473
4474\f
4475
5d538ce3 4476;;;###autoload
9250002f 4477(defun sql-sqlite (&optional buffer)
5d538ce3
JB
4478 "Run sqlite as an inferior process.
4479
4480SQLite is free software.
4481
4482If buffer `*SQL*' exists but no process is running, make a new process.
4483If buffer exists and a process is running, just switch to buffer
4484`*SQL*'.
4485
4486Interpreter used comes from variable `sql-sqlite-program'. Login uses
4487the variables `sql-user', `sql-password', `sql-database', and
4488`sql-server' as defaults, if set. Additional command line parameters
4489can be stored in the list `sql-sqlite-options'.
4490
063c6324 4491The buffer is put in SQL interactive mode, giving commands for sending
5d538ce3
JB
4492input. See `sql-interactive-mode'.
4493
9250002f
MM
4494To set the buffer name directly, use \\[universal-argument]
4495before \\[sql-sqlite]. Once session has started,
4496\\[sql-rename-buffer] can be called separately to rename the
4497buffer.
4498
5d538ce3
JB
4499To specify a coding system for converting non-ASCII characters
4500in the input and output to the process, use \\[universal-coding-system-argument]
4501before \\[sql-sqlite]. You can also specify this with \\[set-buffer-process-coding-system]
4502in the SQL buffer, after you start the process.
4503The default comes from `process-coding-system-alist' and
4504`default-process-coding-system'.
4505
4506\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4507 (interactive "P")
4508 (sql-product-interactive 'sqlite buffer))
78024f88 4509
30c4d8dc 4510(defun sql-comint-sqlite (product options)
7492acc9 4511 "Create comint buffer and connect to SQLite."
78024f88
AS
4512 ;; Put all parameters to the program (if defined) in a list and call
4513 ;; make-comint.
4514 (let ((params))
4515 (if (not (string= "" sql-database))
5474c40f
MM
4516 (setq params (append (list (expand-file-name sql-database))
4517 params)))
7492acc9 4518 (setq params (append options params))
30c4d8dc 4519 (sql-comint product params)))
5d538ce3 4520
fbcc67e2
MM
4521(defun sql-sqlite-completion-object (sqlbuf schema)
4522 (sql-redirect-value sqlbuf ".tables" "\\sw\\(?:\\sw\\|\\s_\\)*" 0))
4523
5d538ce3
JB
4524\f
4525
77d352a6 4526;;;###autoload
9250002f 4527(defun sql-mysql (&optional buffer)
a081a529 4528 "Run mysql by TcX as an inferior process.
dab100d7 4529
058fb10a 4530Mysql versions 3.23 and up are free software.
a081a529 4531
50842164 4532If buffer `*SQL*' exists but no process is running, make a new process.
a081a529
RS
4533If buffer exists and a process is running, just switch to buffer
4534`*SQL*'.
4535
4536Interpreter used comes from variable `sql-mysql-program'. Login uses
dab100d7 4537the variables `sql-user', `sql-password', `sql-database', and
7a65c85c
GM
4538`sql-server' as defaults, if set. Additional command line parameters
4539can be stored in the list `sql-mysql-options'.
a081a529 4540
063c6324 4541The buffer is put in SQL interactive mode, giving commands for sending
a081a529
RS
4542input. See `sql-interactive-mode'.
4543
9250002f
MM
4544To set the buffer name directly, use \\[universal-argument]
4545before \\[sql-mysql]. Once session has started,
4546\\[sql-rename-buffer] can be called separately to rename the
4547buffer.
4548
a081a529
RS
4549To specify a coding system for converting non-ASCII characters
4550in the input and output to the process, use \\[universal-coding-system-argument]
dab100d7 4551before \\[sql-mysql]. You can also specify this with \\[set-buffer-process-coding-system]
a081a529
RS
4552in the SQL buffer, after you start the process.
4553The default comes from `process-coding-system-alist' and
4554`default-process-coding-system'.
4555
4556\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4557 (interactive "P")
4558 (sql-product-interactive 'mysql buffer))
78024f88 4559
30c4d8dc 4560(defun sql-comint-mysql (product options)
7492acc9 4561 "Create comint buffer and connect to MySQL."
78024f88
AS
4562 ;; Put all parameters to the program (if defined) in a list and call
4563 ;; make-comint.
4564 (let ((params))
4565 (if (not (string= "" sql-database))
4566 (setq params (append (list sql-database) params)))
4567 (if (not (string= "" sql-server))
4568 (setq params (append (list (concat "--host=" sql-server)) params)))
9250002f 4569 (if (not (= 0 sql-port))
7492acc9 4570 (setq params (append (list (concat "--port=" (number-to-string sql-port))) params)))
78024f88
AS
4571 (if (not (string= "" sql-password))
4572 (setq params (append (list (concat "--password=" sql-password)) params)))
4573 (if (not (string= "" sql-user))
4574 (setq params (append (list (concat "--user=" sql-user)) params)))
7492acc9 4575 (setq params (append options params))
30c4d8dc 4576 (sql-comint product params)))
95e4b2ef
RS
4577
4578\f
4579
77d352a6 4580;;;###autoload
9250002f 4581(defun sql-solid (&optional buffer)
dab100d7
RS
4582 "Run solsql by Solid as an inferior process.
4583
4584If buffer `*SQL*' exists but no process is running, make a new process.
4585If buffer exists and a process is running, just switch to buffer
4586`*SQL*'.
4587
4588Interpreter used comes from variable `sql-solid-program'. Login uses
4589the variables `sql-user', `sql-password', and `sql-server' as
4590defaults, if set.
4591
063c6324 4592The buffer is put in SQL interactive mode, giving commands for sending
dab100d7
RS
4593input. See `sql-interactive-mode'.
4594
9250002f
MM
4595To set the buffer name directly, use \\[universal-argument]
4596before \\[sql-solid]. Once session has started,
4597\\[sql-rename-buffer] can be called separately to rename the
4598buffer.
4599
dab100d7
RS
4600To specify a coding system for converting non-ASCII characters
4601in the input and output to the process, use \\[universal-coding-system-argument]
4602before \\[sql-solid]. You can also specify this with \\[set-buffer-process-coding-system]
4603in the SQL buffer, after you start the process.
4604The default comes from `process-coding-system-alist' and
4605`default-process-coding-system'.
4606
4607\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4608 (interactive "P")
4609 (sql-product-interactive 'solid buffer))
78024f88 4610
30c4d8dc 4611(defun sql-comint-solid (product options)
7492acc9 4612 "Create comint buffer and connect to Solid."
78024f88
AS
4613 ;; Put all parameters to the program (if defined) in a list and call
4614 ;; make-comint.
7492acc9 4615 (let ((params options))
78024f88
AS
4616 ;; It only makes sense if both username and password are there.
4617 (if (not (or (string= "" sql-user)
4618 (string= "" sql-password)))
4619 (setq params (append (list sql-user sql-password) params)))
4620 (if (not (string= "" sql-server))
4621 (setq params (append (list sql-server) params)))
30c4d8dc 4622 (sql-comint product params)))
dab100d7
RS
4623
4624\f
4625
77d352a6 4626;;;###autoload
9250002f 4627(defun sql-ingres (&optional buffer)
95e4b2ef
RS
4628 "Run sql by Ingres as an inferior process.
4629
dab100d7 4630If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4631If buffer exists and a process is running, just switch to buffer
4632`*SQL*'.
4633
4634Interpreter used comes from variable `sql-ingres-program'. Login uses
4635the variable `sql-database' as default, if set.
4636
063c6324 4637The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4638input. See `sql-interactive-mode'.
4639
9250002f
MM
4640To set the buffer name directly, use \\[universal-argument]
4641before \\[sql-ingres]. Once session has started,
4642\\[sql-rename-buffer] can be called separately to rename the
4643buffer.
4644
95e4b2ef
RS
4645To specify a coding system for converting non-ASCII characters
4646in the input and output to the process, use \\[universal-coding-system-argument]
4647before \\[sql-ingres]. You can also specify this with \\[set-buffer-process-coding-system]
4648in the SQL buffer, after you start the process.
4649The default comes from `process-coding-system-alist' and
4650`default-process-coding-system'.
4651
4652\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4653 (interactive "P")
4654 (sql-product-interactive 'ingres buffer))
78024f88 4655
30c4d8dc 4656(defun sql-comint-ingres (product options)
7492acc9 4657 "Create comint buffer and connect to Ingres."
78024f88 4658 ;; username and password are ignored.
30c4d8dc 4659 (sql-comint product
7492acc9
MM
4660 (append (if (string= "" sql-database)
4661 nil
4662 (list sql-database))
4663 options)))
95e4b2ef
RS
4664
4665\f
4666
77d352a6 4667;;;###autoload
9250002f 4668(defun sql-ms (&optional buffer)
78024f88 4669 "Run osql by Microsoft as an inferior process.
95e4b2ef 4670
dab100d7 4671If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4672If buffer exists and a process is running, just switch to buffer
4673`*SQL*'.
4674
4675Interpreter used comes from variable `sql-ms-program'. Login uses the
dab100d7 4676variables `sql-user', `sql-password', `sql-database', and `sql-server'
f4df536d
JB
4677as defaults, if set. Additional command line parameters can be stored
4678in the list `sql-ms-options'.
95e4b2ef 4679
063c6324 4680The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4681input. See `sql-interactive-mode'.
4682
9250002f
MM
4683To set the buffer name directly, use \\[universal-argument]
4684before \\[sql-ms]. Once session has started,
4685\\[sql-rename-buffer] can be called separately to rename the
4686buffer.
4687
95e4b2ef
RS
4688To specify a coding system for converting non-ASCII characters
4689in the input and output to the process, use \\[universal-coding-system-argument]
dab100d7 4690before \\[sql-ms]. You can also specify this with \\[set-buffer-process-coding-system]
95e4b2ef
RS
4691in the SQL buffer, after you start the process.
4692The default comes from `process-coding-system-alist' and
4693`default-process-coding-system'.
4694
4695\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4696 (interactive "P")
4697 (sql-product-interactive 'ms buffer))
78024f88 4698
30c4d8dc 4699(defun sql-comint-ms (product options)
7492acc9 4700 "Create comint buffer and connect to Microsoft SQL Server."
78024f88
AS
4701 ;; Put all parameters to the program (if defined) in a list and call
4702 ;; make-comint.
7492acc9 4703 (let ((params options))
78024f88 4704 (if (not (string= "" sql-server))
95e4b2ef 4705 (setq params (append (list "-S" sql-server) params)))
78024f88 4706 (if (not (string= "" sql-database))
95e4b2ef 4707 (setq params (append (list "-d" sql-database) params)))
78024f88
AS
4708 (if (not (string= "" sql-user))
4709 (setq params (append (list "-U" sql-user) params)))
4710 (if (not (string= "" sql-password))
4711 (setq params (append (list "-P" sql-password) params))
4712 (if (string= "" sql-user)
4713 ;; if neither user nor password is provided, use system
4714 ;; credentials.
4715 (setq params (append (list "-E") params))
4716 ;; If -P is passed to ISQL as the last argument without a
4717 ;; password, it's considered null.
4718 (setq params (append params (list "-P")))))
30c4d8dc 4719 (sql-comint product params)))
95e4b2ef 4720
95e4b2ef
RS
4721\f
4722
4723;;;###autoload
9250002f 4724(defun sql-postgres (&optional buffer)
95e4b2ef
RS
4725 "Run psql by Postgres as an inferior process.
4726
dab100d7 4727If buffer `*SQL*' exists but no process is running, make a new process.
95e4b2ef
RS
4728If buffer exists and a process is running, just switch to buffer
4729`*SQL*'.
4730
4731Interpreter used comes from variable `sql-postgres-program'. Login uses
c04bb32e 4732the variables `sql-database' and `sql-server' as default, if set.
7a65c85c
GM
4733Additional command line parameters can be stored in the list
4734`sql-postgres-options'.
95e4b2ef 4735
063c6324 4736The buffer is put in SQL interactive mode, giving commands for sending
95e4b2ef
RS
4737input. See `sql-interactive-mode'.
4738
9250002f
MM
4739To set the buffer name directly, use \\[universal-argument]
4740before \\[sql-postgres]. Once session has started,
4741\\[sql-rename-buffer] can be called separately to rename the
4742buffer.
4743
95e4b2ef
RS
4744To specify a coding system for converting non-ASCII characters
4745in the input and output to the process, use \\[universal-coding-system-argument]
4746before \\[sql-postgres]. You can also specify this with \\[set-buffer-process-coding-system]
4747in the SQL buffer, after you start the process.
4748The default comes from `process-coding-system-alist' and
801d1cb0 4749`default-process-coding-system'. If your output lines end with ^M,
95e4b2ef
RS
4750your might try undecided-dos as a coding system. If this doesn't help,
4751Try to set `comint-output-filter-functions' like this:
4752
4753\(setq comint-output-filter-functions (append comint-output-filter-functions
4754 '(comint-strip-ctrl-m)))
4755
4756\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4757 (interactive "P")
4758 (sql-product-interactive 'postgres buffer))
78024f88 4759
30c4d8dc 4760(defun sql-comint-postgres (product options)
7492acc9 4761 "Create comint buffer and connect to Postgres."
78024f88
AS
4762 ;; username and password are ignored. Mark Stosberg suggest to add
4763 ;; the database at the end. Jason Beegan suggest using --pset and
4764 ;; pager=off instead of \\o|cat. The later was the solution by
4765 ;; Gregor Zych. Jason's suggestion is the default value for
4766 ;; sql-postgres-options.
7492acc9 4767 (let ((params options))
78024f88
AS
4768 (if (not (string= "" sql-database))
4769 (setq params (append params (list sql-database))))
4770 (if (not (string= "" sql-server))
4771 (setq params (append (list "-h" sql-server) params)))
9fd8cb36
SM
4772 (if (not (string= "" sql-user))
4773 (setq params (append (list "-U" sql-user) params)))
74790210 4774 (if (not (= 0 sql-port))
7e423bb8 4775 (setq params (append (list "-p" (number-to-string sql-port)) params)))
30c4d8dc 4776 (sql-comint product params)))
95e4b2ef 4777
fbcc67e2
MM
4778(defun sql-postgres-completion-object (sqlbuf schema)
4779 (let (cl re fs a r)
4780 (sql-redirect sqlbuf "\\t on")
4781 (setq a (car (sql-redirect-value sqlbuf "\\a" "Output format is \\(.*\\)[.]$" 1)))
4782 (when (string= a "aligned")
4783 (sql-redirect sqlbuf "\\a"))
4784 (setq fs (or (car (sql-redirect-value sqlbuf "\\f" "Field separator is \"\\(.\\)[.]$" 1)) "|"))
4785
4786 (setq re (concat "^\\([^" fs "]*\\)" fs "\\([^" fs "]*\\)" fs "[^" fs "]*" fs "[^" fs "]*$"))
4787 (setq cl (if (not schema)
4788 (sql-redirect-value sqlbuf "\\d" re '(1 2))
4789 (append (sql-redirect-value sqlbuf (format "\\dt %s.*" schema) re '(1 2))
4790 (sql-redirect-value sqlbuf (format "\\dv %s.*" schema) re '(1 2))
4791 (sql-redirect-value sqlbuf (format "\\ds %s.*" schema) re '(1 2)))))
4792
4793 ;; Restore tuples and alignment to what they were
4794 (sql-redirect sqlbuf "\\t off")
4795 (when (not (string= a "aligned"))
4796 (sql-redirect sqlbuf "\\a"))
91af3942
PE
4797
4798 ;; Return the list of table names (public schema name can be omitted)
fbcc67e2
MM
4799 (mapcar (lambda (tbl)
4800 (if (string= (car tbl) "public")
4801 (cadr tbl)
4802 (format "%s.%s" (car tbl) (cadr tbl))))
4803 cl)))
4804
eb3f61dd
GM
4805\f
4806
4807;;;###autoload
9250002f 4808(defun sql-interbase (&optional buffer)
eb3f61dd
GM
4809 "Run isql by Interbase as an inferior process.
4810
4811If buffer `*SQL*' exists but no process is running, make a new process.
4812If buffer exists and a process is running, just switch to buffer
4813`*SQL*'.
4814
4815Interpreter used comes from variable `sql-interbase-program'. Login
4816uses the variables `sql-user', `sql-password', and `sql-database' as
4817defaults, if set.
4818
063c6324 4819The buffer is put in SQL interactive mode, giving commands for sending
eb3f61dd
GM
4820input. See `sql-interactive-mode'.
4821
9250002f
MM
4822To set the buffer name directly, use \\[universal-argument]
4823before \\[sql-interbase]. Once session has started,
4824\\[sql-rename-buffer] can be called separately to rename the
4825buffer.
4826
eb3f61dd
GM
4827To specify a coding system for converting non-ASCII characters
4828in the input and output to the process, use \\[universal-coding-system-argument]
4829before \\[sql-interbase]. You can also specify this with \\[set-buffer-process-coding-system]
4830in the SQL buffer, after you start the process.
4831The default comes from `process-coding-system-alist' and
4832`default-process-coding-system'.
4833
4834\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4835 (interactive "P")
4836 (sql-product-interactive 'interbase buffer))
78024f88 4837
30c4d8dc 4838(defun sql-comint-interbase (product options)
7492acc9 4839 "Create comint buffer and connect to Interbase."
78024f88
AS
4840 ;; Put all parameters to the program (if defined) in a list and call
4841 ;; make-comint.
7492acc9 4842 (let ((params options))
78024f88
AS
4843 (if (not (string= "" sql-user))
4844 (setq params (append (list "-u" sql-user) params)))
4845 (if (not (string= "" sql-password))
4846 (setq params (append (list "-p" sql-password) params)))
4847 (if (not (string= "" sql-database))
4848 (setq params (cons sql-database params))) ; add to the front!
30c4d8dc 4849 (sql-comint product params)))
eb3f61dd 4850
624ef9b3
GM
4851\f
4852
4853;;;###autoload
9250002f 4854(defun sql-db2 (&optional buffer)
624ef9b3
GM
4855 "Run db2 by IBM as an inferior process.
4856
4857If buffer `*SQL*' exists but no process is running, make a new process.
4858If buffer exists and a process is running, just switch to buffer
4859`*SQL*'.
4860
4861Interpreter used comes from variable `sql-db2-program'. There is not
4862automatic login.
4863
063c6324 4864The buffer is put in SQL interactive mode, giving commands for sending
624ef9b3
GM
4865input. See `sql-interactive-mode'.
4866
aa88e662
GM
4867If you use \\[sql-accumulate-and-indent] to send multiline commands to
4868db2, newlines will be escaped if necessary. If you don't want that, set
4869`comint-input-sender' back to `comint-simple-send' by writing an after
4870advice. See the elisp manual for more information.
624ef9b3 4871
9250002f
MM
4872To set the buffer name directly, use \\[universal-argument]
4873before \\[sql-db2]. Once session has started,
4874\\[sql-rename-buffer] can be called separately to rename the
4875buffer.
4876
624ef9b3
GM
4877To specify a coding system for converting non-ASCII characters
4878in the input and output to the process, use \\[universal-coding-system-argument]
4879before \\[sql-db2]. You can also specify this with \\[set-buffer-process-coding-system]
4880in the SQL buffer, after you start the process.
4881The default comes from `process-coding-system-alist' and
4882`default-process-coding-system'.
4883
4884\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4885 (interactive "P")
4886 (sql-product-interactive 'db2 buffer))
78024f88 4887
30c4d8dc 4888(defun sql-comint-db2 (product options)
7492acc9 4889 "Create comint buffer and connect to DB2."
78024f88
AS
4890 ;; Put all parameters to the program (if defined) in a list and call
4891 ;; make-comint.
fbcc67e2 4892 (sql-comint product options))
624ef9b3 4893
f4df536d 4894;;;###autoload
9250002f 4895(defun sql-linter (&optional buffer)
f4df536d
JB
4896 "Run inl by RELEX as an inferior process.
4897
4898If buffer `*SQL*' exists but no process is running, make a new process.
4899If buffer exists and a process is running, just switch to buffer
4900`*SQL*'.
4901
4902Interpreter used comes from variable `sql-linter-program' - usually `inl'.
4903Login uses the variables `sql-user', `sql-password', `sql-database' and
4904`sql-server' as defaults, if set. Additional command line parameters
7492acc9 4905can be stored in the list `sql-linter-options'. Run inl -h to get help on
f4df536d
JB
4906parameters.
4907
4908`sql-database' is used to set the LINTER_MBX environment variable for
4909local connections, `sql-server' refers to the server name from the
4910`nodetab' file for the network connection (dbc_tcp or friends must run
4911for this to work). If `sql-password' is an empty string, inl will use
4912an empty password.
4913
063c6324 4914The buffer is put in SQL interactive mode, giving commands for sending
f4df536d
JB
4915input. See `sql-interactive-mode'.
4916
9250002f
MM
4917To set the buffer name directly, use \\[universal-argument]
4918before \\[sql-linter]. Once session has started,
4919\\[sql-rename-buffer] can be called separately to rename the
4920buffer.
4921
f4df536d 4922\(Type \\[describe-mode] in the SQL buffer for a list of commands.)"
9250002f
MM
4923 (interactive "P")
4924 (sql-product-interactive 'linter buffer))
78024f88 4925
30c4d8dc 4926(defun sql-comint-linter (product options)
7492acc9 4927 "Create comint buffer and connect to Linter."
78024f88
AS
4928 ;; Put all parameters to the program (if defined) in a list and call
4929 ;; make-comint.
7492acc9
MM
4930 (let ((params options)
4931 (login nil)
4932 (old-mbx (getenv "LINTER_MBX")))
78024f88
AS
4933 (if (not (string= "" sql-user))
4934 (setq login (concat sql-user "/" sql-password)))
4935 (setq params (append (list "-u" login) params))
4936 (if (not (string= "" sql-server))
4937 (setq params (append (list "-n" sql-server) params)))
4938 (if (string= "" sql-database)
4939 (setenv "LINTER_MBX" nil)
4940 (setenv "LINTER_MBX" sql-database))
30c4d8dc 4941 (sql-comint product params)
78024f88 4942 (setenv "LINTER_MBX" old-mbx)))
f4df536d
JB
4943
4944\f
4945
95e4b2ef
RS
4946(provide 'sql)
4947
4948;;; sql.el ends here
fbcc67e2
MM
4949
4950; LocalWords: sql SQL SQLite sqlite Sybase Informix MySQL
4951; LocalWords: Postgres SQLServer SQLi