[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/sql-indent 9f716f6 09/13: Recognize PostgreSQL $$ quote
From: |
Stefan Monnier |
Subject: |
[elpa] externals/sql-indent 9f716f6 09/13: Recognize PostgreSQL $$ quote syntax, #54 (#55) |
Date: |
Sun, 11 Feb 2018 22:24:14 -0500 (EST) |
branch: externals/sql-indent
commit 9f716f6ad8adfca9f8ea595d5b5ee71f781921c9
Author: Alex Harsányi <address@hidden>
Commit: GitHub <address@hidden>
Recognize PostgreSQL $$ quote syntax, #54 (#55)
Function bodies in PostgreSQL are defined between '$$' markers. The code
now
recognizes these as begin/end statements. There's a test file,
`test-data/pr54.sql`, specifying the cases that are correctly detected.
PostgreSQL support likely needs more work.
---
sql-indent-test.el | 4 +++
sql-indent.el | 46 ++++++++++++++++++++++++++++++++---
test-data/pr54-syn.eld | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
test-data/pr54.sql | 29 ++++++++++++++++++++++
4 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/sql-indent-test.el b/sql-indent-test.el
index 8361be2..ebe8dba 100644
--- a/sql-indent-test.el
+++ b/sql-indent-test.el
@@ -362,4 +362,8 @@ information read from DATA-FILE (as generated by
(ert-deftest sqlind-ert-pr53-io-left ()
(sqlind-ert-check-file-indentation "test-data/pr53.sql"
"test-data/pr53-io-left.eld"
sqlind-indentation-left-offsets-alist 2))
+
+(ert-deftest sqlind-ert-pr54 ()
+ (sqlind-ert-check-file-syntax "test-data/pr54.sql" "test-data/pr54-syn.eld"))
+
;;; sql-indent-test.el ends here
diff --git a/sql-indent.el b/sql-indent.el
index 8d53878..fcde79f 100644
--- a/sql-indent.el
+++ b/sql-indent.el
@@ -741,11 +741,40 @@ See also `sqlind-beginning-of-block'"
(progn (forward-word -1) (looking-at "\\<_begin\\_>")))
(throw 'finished (list 'in-block 'exception))))))
+(defun sqlind-maybe-$$-statement ()
+ "If (point) is on a PostgreSQL $$ quote, report its syntax.
+
+PostgreSQL uses $$ to delimit SQL blocks in create statements,
+this function tries to determine if the $$ block is a begin or an
+end block and creates the appropiate syntactic context.
+
+See also `sqlind-beginning-of-block'"
+ (when (looking-at "\\$\\$")
+ (prog1 t
+ (let* ((saved-pos (point))
+ (previous-block (save-excursion
+ (ignore-errors (forward-char -1))
+ (cons (sqlind-beginning-of-block) (point))))
+ (previous-block-kind (nth 0 previous-block)))
+ (goto-char saved-pos)
+ (if (and (listp previous-block-kind)
+ (eq (nth 0 previous-block-kind) 'defun-start))
+ (progn
+ (when (null sqlind-end-stmt-stack)
+ (throw 'finished (list 'in-begin-block 'defun (nth 1
previous-block-kind))))
+ (cl-destructuring-bind (pos kind _label) (pop
sqlind-end-stmt-stack)
+ (unless (eq kind '$$)
+ (throw 'finished
+ (list 'syntax-error "bad closing for $$ begin block"
(point) pos)))
+ (goto-char (cdr previous-block))))
+ ;; Assume it is an "end" statement
+ (push (list (point) '$$ "") sqlind-end-stmt-stack))))))
+
(defconst sqlind-start-block-regexp
(concat "\\(\\_<"
(regexp-opt '("if" "then" "else" "elsif" "loop"
"begin" "declare" "create" "alter" "exception"
- "procedure" "function" "end" "case") t)
+ "procedure" "function" "end" "case" "$$") t)
"\\_>\\)\\|)")
"Regexp to match the start of a block.")
@@ -770,6 +799,8 @@ reverse order (a stack) and is used to skip over nested
blocks."
(sqlind-maybe-begin-statement)
(when (eq sql-product 'oracle) ; declare statements only start
blocks in PL/SQL
(sqlind-maybe-declare-statement))
+ (when (eq sql-product 'postgres)
+ (sqlind-maybe-$$-statement))
(sqlind-maybe-create-statement)
(sqlind-maybe-defun-statement))))
'toplevel))
@@ -1325,7 +1356,8 @@ not a statement-continuation POS is the same as the
;; context
((and (memq syntax-symbol '(defun-start declare-statement toplevel
package package-body))
- (looking-at "begin\\_>"))
+ (or (looking-at "begin\\_>")
+ (and (eq sql-product 'postgres) (looking-at "\\$\\$"))))
(push (cons (list 'block-start 'begin) anchor) context))
((and (memq syntax-symbol '(defun-start package package-body))
@@ -1367,7 +1399,15 @@ not a statement-continuation POS is the same as the
(push (sqlind-refine-end-syntax
(if (equal kind "") nil (intern kind))
label (point) context)
- context))))
+ context)))
+
+ ((and (eq sql-product 'postgres)
+ (not (eq syntax-symbol 'comment-continuation))
+ (looking-at "\\$\\$"))
+ (push (sqlind-refine-end-syntax
+ nil "" (point) context)
+ context))
+ )
context))
(defun sqlind-syntax-of-line ()
diff --git a/test-data/pr54-syn.eld b/test-data/pr54-syn.eld
new file mode 100644
index 0000000..40abbbe
--- /dev/null
+++ b/test-data/pr54-syn.eld
@@ -0,0 +1,66 @@
+(((toplevel . 1))
+ (((block-start begin)
+ . 1)
+ ((defun-start "foo_1")
+ . 1))
+ (((in-begin-block defun "foo_1")
+ . 40))
+ (((block-end defun "foo_1")
+ . 40)
+ ((in-begin-block defun "foo_1")
+ . 40))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ (((in-begin-block defun "foo_2")
+ . 99))
+ (((block-end defun "foo_2")
+ . 99)
+ ((in-begin-block defun "foo_2")
+ . 99))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ (((block-start is-or-as)
+ . 197)
+ ((defun-start "foo_3")
+ . 197))
+ (((in-begin-block defun "foo_3")
+ . 236))
+ (((block-end defun "foo_3")
+ . 236)
+ ((in-begin-block defun "foo_3")
+ . 236))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ (((block-start is-or-as)
+ . 262)
+ ((defun-start "foo_4")
+ . 262))
+ (((block-start begin)
+ . 262)
+ ((defun-start "foo_4")
+ . 262))
+ (((in-begin-block defun "foo_4")
+ . 301))
+ (((block-end defun "foo_4")
+ . 301)
+ ((in-begin-block defun "foo_4")
+ . 301))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((toplevel . 1)))
+
\ No newline at end of file
diff --git a/test-data/pr54.sql b/test-data/pr54.sql
new file mode 100644
index 0000000..34483fa
--- /dev/null
+++ b/test-data/pr54.sql
@@ -0,0 +1,29 @@
+create function foo_1() returns int AS
+$$
+ select 5;
+$$;
+
+create function foo_2() returns int AS $$
+ select 5;
+$$;
+
+create function foo_3() returns int
+AS $$
+ select 5;
+$$;
+
+create function foo_4() returns int
+AS
+$$
+ select 5;
+$$;
+
+SELECT a();
+
+-- Local Variables:
+-- mode: sql
+-- mode: sqlind-minor
+-- tab-width: 2
+-- indent-tabs-mode: nil
+-- sql-product: postgres
+-- End:
- [elpa] externals/sql-indent updated (c3d49c6 -> 44841a8), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent bd39d07 10/13: add explanation on how `sqlind-beginning-of-block` works, Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 2c9c17f 07/13: Fix typo in sql-indent.org. (#56), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 283116d 04/13: Correct the adjustment of indentation for operators in select (#52), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 51b17d6 01/13: Update README with instructions on how to install from GNU ELPA, Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 0bca299 12/13: Fix travis build. (#58), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 44841a8 13/13: Add .elpaignore file, Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 1b4d0e8 03/13: Add CONTRIBUTING.md file (#51), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 3ee7f95 08/13: Fix various typos here and there. (#57), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent d56faed 06/13: Updated documentation, Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 9f716f6 09/13: Recognize PostgreSQL $$ quote syntax, #54 (#55),
Stefan Monnier <=
- [elpa] externals/sql-indent 8a1c4ec 05/13: Correct indentation of column continuation with operators. (#53), Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 1efac21 11/13: Update sql-indent.el to version 1.1, Stefan Monnier, 2018/02/11
- [elpa] externals/sql-indent 146655b 02/13: Add new indentation function for select columns. (#50), Stefan Monnier, 2018/02/11