[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/sql-indent b694078 2/9: CREATE TABLE, VIEW and INDEX do
From: |
Alex Harsanyi |
Subject: |
[elpa] externals/sql-indent b694078 2/9: CREATE TABLE, VIEW and INDEX does not start a block (#89) |
Date: |
Fri, 20 Mar 2020 19:08:02 -0400 (EDT) |
branch: externals/sql-indent
commit b6940780678e95af245830dbcd897672ca0a0a4c
Author: Alex Harsanyi <address@hidden>
Commit: Alex Harsanyi <address@hidden>
CREATE TABLE, VIEW and INDEX does not start a block (#89)
A CREATE TABLE, VIEW or INDEX statement is not a block start and can confuse
the parser if such statements appear inside BEGIN/END blocks. See
test-data/pr89.sql for example test cases.
* sql-indent-test.el (sqlind-ert-pr89): add test case for issue #89
* sql-indent.el (sqlind-maybe-create-statement): add the ALL-STATEMENTS
argument which controls whether create table/view/index statements are
recognized. Defaults to false, so these statements are not considered
block
start statements anymore.
(sqlind-maybe-$$-statement): also recognize an "end" keyword before the $$
as marking an ending "quote"
(sqlind-syntax-of-line): don't treat create table/view/index statements as
having block context, but refine a 'statement-continuation context into a
'create-table one, if the statement start is appropriate.
---
sql-indent-test.el | 5 ++++
sql-indent.el | 79 +++++++++++++++++++++++++++++++++-----------------
test-data/pr89-syn.eld | 68 +++++++++++++++++++++++++++++++++++++++++++
test-data/pr89.sql | 31 ++++++++++++++++++++
4 files changed, 157 insertions(+), 26 deletions(-)
diff --git a/sql-indent-test.el b/sql-indent-test.el
index 235fa7f..38af1c0 100644
--- a/sql-indent-test.el
+++ b/sql-indent-test.el
@@ -427,4 +427,9 @@ information read from DATA-FILE (as generated by
"test-data/pr87.sql"
"test-data/pr87-syn.eld"))
+(ert-deftest sqlind-ert-pr89 ()
+ (sqlind-ert-check-file-syntax
+ "test-data/pr89.sql"
+ "test-data/pr89-syn.eld"))
+
;;; sql-indent-test.el ends here
diff --git a/sql-indent.el b/sql-indent.el
index d77a73c..0496a53 100644
--- a/sql-indent.el
+++ b/sql-indent.el
@@ -721,9 +721,14 @@ present."
(sqlind-forward-syntactic-ws))
(t (throw 'finished nil))))))))
-(defun sqlind-maybe-create-statement ()
+(defun sqlind-maybe-create-statement (&optional all-statements)
"If (point) is on a CREATE statement, report its syntax.
-See also `sqlind-beginning-of-block'"
+See also `sqlind-beginning-of-block'
+
+Normally, only block start create statements are considered (such
+as creation of procedures). In particular, create
+table/view/index statements are ignored unless the ALL-STATEMENTS
+argument is t"
(when (or (looking-at "create\\_>\\(?:[ \t\n\r\f]+\\)\\(or\\(?:[
\t\n\r\f]+\\)replace\\_>\\)?")
(looking-at "alter\\_>"))
(prog1 t ; make sure we return t
@@ -755,30 +760,34 @@ See also `sqlind-beginning-of-block'"
(when (string-match "\\(.*?\\)(" name)
(setq name (match-string 1 name)))
- (if (memq what '(procedure function package package-body))
- ;; check is name is in the form user.name, if so then suppress
user part.
- (progn
- (when (string-match "\\(?:.*\\.\\)?\\(.*\\)" name)
- (setq name (match-string 1 name)))
- (if (null sqlind-end-stmt-stack)
- (throw 'finished
- (list (if (memq what '(procedure function)) 'defun-start what)
- name))
- (cl-destructuring-bind (pos kind label) (pop
sqlind-end-stmt-stack)
- (when (not (eq kind nil))
- (throw 'finished
- (list 'syntax-error
- "bad closing for create block" (point) pos)))
- (unless (sqlind-labels-match label name)
- (throw 'finished
- (list 'syntax-error
- "label mismatch in create block" (point) pos))))))
- ;; we are creating a non-code block thing: table, view,
- ;; index, etc. These things only exist at toplevel.
- (unless (null sqlind-end-stmt-stack)
- (throw 'finished
- (list 'syntax-error "nested create statement" (point) (point))))
- (throw 'finished (list 'create-statement what name))))))))
+ (cond
+ ((memq what '(procedure function package package-body))
+ ;; check is name is in the form user.name, if so then suppress
user part.
+ (when (string-match "\\(?:.*\\.\\)?\\(.*\\)" name)
+ (setq name (match-string 1 name)))
+ (if (null sqlind-end-stmt-stack)
+ (throw 'finished
+ (list (if (memq what '(procedure function)) 'defun-start
what)
+ name))
+ (cl-destructuring-bind (pos kind label) (pop
sqlind-end-stmt-stack)
+ (when (not (eq kind nil))
+ (throw 'finished
+ (list 'syntax-error
+ "bad closing for create block" (point) pos)))
+ (unless (sqlind-labels-match label name)
+ (throw 'finished
+ (list 'syntax-error
+ "label mismatch in create block" (point) pos))))))
+ ((memq what '(table view index))
+ ;; Table, view and index creations do not begin blocks and they
+ ;; are ignored unless the ALL-STATEMENTS parameter is t
+ (when all-statements
+ (throw 'finished (list 'create-statement what name))))
+ (t
+ (unless (null sqlind-end-stmt-stack)
+ (throw 'finished
+ (list 'syntax-error "nested create statement" (point)
(point))))
+ (throw 'finished (list 'create-statement what name)))))))))
(defun sqlind-maybe-defun-statement ()
"If (point) is on a procedure definition statement, report its syntax.
@@ -868,6 +877,12 @@ See also `sqlind-beginning-of-block'"
;; which ends another statement)
(push (list saved-pos '$$ "") sqlind-end-stmt-stack)
(goto-char saved-pos))
+ ((progn (forward-word -1)
+ (looking-at "end"))
+ ;; Assume the $$ is ending a statement (previous line contains
+ ;; an "end" keyword)
+ (push (list saved-pos '$$ "") sqlind-end-stmt-stack)
+ (goto-char saved-pos))
((null sqlind-end-stmt-stack)
(sqlind-beginning-of-statement)
(let ((syntax (catch 'finished
@@ -1604,6 +1619,10 @@ procedure block."
(goto-char context-start)
(when (or (>= context-start pos)
(and (looking-at sqlind-start-block-regexp)
+ ;; create table/view/index statements are not block
+ ;; contexts
+ (or (not (looking-at "\\(create\\)\\|\\(alter\\)"))
+ (catch 'finished (sqlind-maybe-create-statement)
nil))
(not (sqlind-looking-at-begin-transaction))))
(goto-char pos)
;; if we are at the start of a statement, or the nearest statement
@@ -1626,6 +1645,14 @@ procedure block."
(setq context-start (point))
(setq context (list (cons block-info context-start))))))
+ (goto-char context-start)
+ (when (and (eq 'statement-continuation (sqlind-syntax-symbol context))
+ (looking-at "\\(create\\)\\|\\(alter\\)"))
+ (let ((create-info (catch 'finished (sqlind-maybe-create-statement
t) nil)))
+ (when create-info
+ (pop context) ; remove the statement continuation syntax
+ (push (cons create-info context-start) context))))
+
(let ((parse-info (syntax-ppss pos)))
(cond ((nth 4 parse-info) ; inside a comment
(push (cons 'comment-continuation (nth 8 parse-info))
context))
diff --git a/test-data/pr89-syn.eld b/test-data/pr89-syn.eld
new file mode 100644
index 0000000..2f0a245
--- /dev/null
+++ b/test-data/pr89-syn.eld
@@ -0,0 +1,68 @@
+(((comment-start . 1)
+ (toplevel . 1))
+ ((toplevel . 1))
+ ((statement-continuation . 46))
+ (((in-begin-block nil "")
+ . 54))
+ (((block-end nil "")
+ . 54)
+ ((in-begin-block nil "")
+ . 54))
+ (((block-end toplevel nil)
+ . 46)
+ ((in-begin-block toplevel nil)
+ . 46))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((statement-continuation . 111))
+ (((in-begin-block nil "")
+ . 119))
+ (((create-statement table "t")
+ . 129))
+ (((block-end nil "")
+ . 119)
+ ((in-begin-block nil "")
+ . 119))
+ (((block-end toplevel nil)
+ . 111)
+ ((in-begin-block toplevel nil)
+ . 111))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((statement-continuation . 199))
+ (((in-begin-block nil "")
+ . 207))
+ (((create-statement view "t")
+ . 217))
+ ((select-clause . 240)
+ ((create-statement view "t")
+ . 217))
+ (((block-end nil "")
+ . 207)
+ ((in-begin-block nil "")
+ . 207))
+ (((block-end toplevel nil)
+ . 199)
+ ((in-begin-block toplevel nil)
+ . 199))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((statement-continuation . 295))
+ (((in-begin-block nil "")
+ . 303))
+ (((block-end nil "")
+ . 303)
+ ((in-begin-block nil "")
+ . 303))
+ (((block-end toplevel nil)
+ . 295)
+ ((in-begin-block toplevel nil)
+ . 295))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ (((create-statement view "t")
+ . 369))
+ ((select-clause . 388)
+ ((create-statement view "t")
+ . 369))
+ ((toplevel . 1)))
diff --git a/test-data/pr89.sql b/test-data/pr89.sql
new file mode 100644
index 0000000..cf37d7a
--- /dev/null
+++ b/test-data/pr89.sql
@@ -0,0 +1,31 @@
+-- -*- mode: sql; sql-product: postgres; -*-
+do $$
+ begin
+ create table t ();
+ end
+$$ language plpgsql;
+
+do $$
+ begin
+ alter table t
+ add column c integer;
+ end
+$$ language plpgsql;
+
+do $$
+ begin
+ create view t as
+ select *
+ from foo;
+ end
+$$ language plpgsql;
+
+do $$
+ begin
+ create index t on foo(bar);
+ end
+$$ language plpgsql;
+
+create view t as
+ select *
+ from foo;
- [elpa] externals/sql-indent updated (08f0417 -> dad9605), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent 7f649aa 1/9: Fix indentation for create schema if not exists (fixes #87), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent b694078 2/9: CREATE TABLE, VIEW and INDEX does not start a block (#89),
Alex Harsanyi <=
- [elpa] externals/sql-indent 56be397 4/9: Create GH Action for build and test (#91), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent f75d7a7 3/9: Fixes to function and procedure block detection (#88, #90), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent e7795c7 6/9: Mode refinements in recognizing declare statements (#92), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent dad9605 9/9: Release 1.5, remove Travis, add GitHub Actions status badge, Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent 5656cfb 8/9: Document limitations of recognizing DECLARE statements (#92), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent 7edd915 7/9: fixups for indenting where clauses (#93), Alex Harsanyi, 2020/03/20
- [elpa] externals/sql-indent 1bb06f8 5/9: Fix detection of DECLARE blocks in PostgresSQL (#92), Alex Harsanyi, 2020/03/20