emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/sql-indent 47e9ccb 13/13: Recognize left and right oute


From: Alex Harsanyi
Subject: [elpa] externals/sql-indent 47e9ccb 13/13: Recognize left and right outer join statements #85
Date: Thu, 20 Jun 2019 05:25:47 -0400 (EDT)

branch: externals/sql-indent
commit 47e9ccbd06b327320a47dd1da778e6797b7608ce
Author: Alex Harsanyi <address@hidden>
Commit: Alex Harsanyi <address@hidden>

    Recognize left and right outer join statements #85
    
    * sql-indent.el (sqlind-find-join-start): new defun to look for
    join statements, can find "left outer join" statements as well,
    see #85
    (sqlind-syntax-in-select, sqlind-refine-syntax): use
    `sqlind-find-join-start`
    (sqlind-lineup-joins-to-anchor): only look for the first join
    keyword, to detect the case where they un on multiple lines
---
 sql-indent-test.el     |  5 +++++
 sql-indent.el          | 56 ++++++++++++++++++++++++++++++++-----------------
 test-data/pr85-syn.eld | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 test-data/pr85.sql     | 33 +++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+), 19 deletions(-)

diff --git a/sql-indent-test.el b/sql-indent-test.el
index f8181d4..f9a5910 100644
--- a/sql-indent-test.el
+++ b/sql-indent-test.el
@@ -417,4 +417,9 @@ information read from DATA-FILE (as generated by
    "test-data/pr84.sql"
    "test-data/pr84-syn.eld"))
 
+(ert-deftest sqlind-ert-pr85 ()
+  (sqlind-ert-check-file-syntax
+   "test-data/pr85.sql"
+   "test-data/pr85-syn.eld"))
+
 ;;; sql-indent-test.el ends here
diff --git a/sql-indent.el b/sql-indent.el
index 112b05a..8511150 100644
--- a/sql-indent.el
+++ b/sql-indent.el
@@ -1022,6 +1022,32 @@ reverse order (a stack) and is used to skip over nested 
blocks."
 (defconst sqlind-join-condition-regexp
   (regexp-opt '("on" "using" "and" "or") 'symbols))
 
+(defun sqlind-find-join-start (start limit)
+  "Look backwards for the start of a JOIN statement,
+begin looking for it at the START position in the buffer, and
+look backwards until LIMIT is reached.  Returns the buffer
+position where the JOIN condition starts, or nil if no JOIN
+statement is found."
+  (save-excursion
+    (when (sqlind-search-backward start "\\bjoin\\b" limit)
+      (let ((candidate (point)))
+        (forward-char -1)
+        (sqlind-backward-syntactic-ws)
+        (backward-word)
+        (if (looking-at sqlind-select-join-regexp)
+            (point)
+          ;; The "outer" keyword is composed with a "left" or "right" keyword
+          ;; so we need to move backwards one more word.
+          (if (looking-at "\\bouter\\b")
+              (progn
+                (forward-char -1)
+                (sqlind-backward-syntactic-ws)
+                (backward-word)
+                (if (looking-at "\\b\\(left\\|right\\)\\b")
+                    (point)
+                  candidate))
+            candidate))))))
+
 (defun sqlind-syntax-in-select (pos start)
   "Return the syntax ar POS which is inside a \"select\" statement at START."
   (save-excursion
@@ -1069,15 +1095,9 @@ reverse order (a stack) and is used to skip over nested 
blocks."
                 (when (or (looking-at sqlind-join-condition-regexp)
                           (progn (forward-word -1) (looking-at 
sqlind-select-join-regexp)))
                   ;; look for the join start, that will be the anchor
-                   (when (sqlind-search-backward (point) "\\bjoin\\b" start)
-                     (let ((candidate (point)))
-                       (forward-char -1)
-                       (sqlind-backward-syntactic-ws)
-                       (backward-word)
-                       (throw 'finished
-                         (if (looking-at sqlind-select-join-regexp)
-                             (cons 'select-join-condition (point))
-                           (cons 'select-join-condition candidate)))))))
+                   (let ((jstart (sqlind-find-join-start (point) start)))
+                     (when jstart
+                       (throw 'finished (cons 'select-join-condition 
jstart))))))
 
               ;; if this line starts with a ',' or the previous line starts
               ;; with a ',', we have a new table
@@ -1478,15 +1498,9 @@ not a statement-continuation POS is the same as the
             (when (or (looking-at sqlind-join-condition-regexp)
                       (progn (forward-word -1) (looking-at 
sqlind-join-condition-regexp)))
               ;; look for the join start, that will be the anchor
-               (when (sqlind-search-backward (point) "\\bjoin\\b" anchor)
-                 (let ((candidate (point)))
-                   (forward-char -1)
-                   (sqlind-backward-syntactic-ws)
-                   (backward-word)
-                   (push (if (looking-at sqlind-select-join-regexp)
-                             (cons 'select-join-condition (point))
-                           (cons 'select-join-condition candidate))
-                         context))))))
+               (let ((jstart (sqlind-find-join-start (point) anchor)))
+                 (when jstart
+                   (push (cons 'select-join-condition jstart) context))))))
 
          ))
 
@@ -2236,7 +2250,11 @@ it will indent lines starting with JOIN keywords to line 
up with
 the FROM keyword."
   (save-excursion
     (back-to-indentation)
-    (if (looking-at (concat "\\b\\(" sqlind-select-join-regexp 
"\\s-+\\)?join\\b"))
+    ;; NOTE: we are a bit loose here as we only look for the first keyword
+    ;; which might indicate a join regexp, e.g. we are happy to see "left"
+    ;; even though, the correct statement is "left outer? join"
+    (if (or (looking-at sqlind-select-join-regexp)
+            (looking-at "\\bjoin\\b"))
         (sqlind-lineup-to-anchor syntax base-indentation)
       base-indentation)))
 
diff --git a/test-data/pr85-syn.eld b/test-data/pr85-syn.eld
new file mode 100644
index 0000000..7710e7d
--- /dev/null
+++ b/test-data/pr85-syn.eld
@@ -0,0 +1,57 @@
+(((toplevel . 1))
+ ((select-clause . 1)
+  (statement-continuation . 1))
+ ((select-table-continuation . 12)
+  (statement-continuation . 1))
+ ((select-join-condition . 30)
+  (statement-continuation . 1))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((select-clause . 82)
+  (statement-continuation . 82))
+ ((select-table-continuation . 93)
+  (statement-continuation . 82))
+ ((select-table-continuation . 93)
+  (statement-continuation . 82))
+ ((select-join-condition . 111)
+  (statement-continuation . 82))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((select-clause . 172)
+  (statement-continuation . 172))
+ ((select-table-continuation . 183)
+  (statement-continuation . 172))
+ ((select-table-continuation . 183)
+  (statement-continuation . 172))
+ ((select-join-condition . 201)
+  (statement-continuation . 172))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((select-clause . 290)
+  (statement-continuation . 290))
+ ((select-table-continuation . 301)
+  (statement-continuation . 290))
+ ((select-join-condition . 319)
+  (statement-continuation . 290))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((select-clause . 372)
+  (statement-continuation . 372))
+ ((select-table-continuation . 383)
+  (statement-continuation . 372))
+ ((select-table-continuation . 383)
+  (statement-continuation . 372))
+ ((select-join-condition . 401)
+  (statement-continuation . 372))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((select-clause . 496)
+  (statement-continuation . 496))
+ ((select-table-continuation . 507)
+  (statement-continuation . 496))
+ ((select-table-continuation . 507)
+  (statement-continuation . 496))
+ ((select-join-condition . 525)
+  (statement-continuation . 496))
+ ((toplevel . 1)))
+ 
\ No newline at end of file
diff --git a/test-data/pr85.sql b/test-data/pr85.sql
new file mode 100644
index 0000000..7dd8aa7
--- /dev/null
+++ b/test-data/pr85.sql
@@ -0,0 +1,33 @@
+select *
+  from foo
+  left outer join bar
+      on foo.k = bar.k;
+
+select *
+  from foo
+  left
+         outer join bar
+      on foo.k = bar.k;
+
+select *
+  from foo
+  left outer                     -- test
+  join bar
+      on foo.k = bar.k;
+
+select *
+  from foo
+  right outer join bar
+      on foo.k = bar.k;
+
+select *
+  from foo
+  right                          -- test
+         outer join bar
+      on foo.k = bar.k;
+
+select *
+  from foo
+  right outer
+  join bar
+      on foo.k = bar.k;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]