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