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