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

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

[nongnu] elpa/emacsql 364c3cacb6 133/427: More advanced :from sources, a


From: ELPA Syncer
Subject: [nongnu] elpa/emacsql 364c3cacb6 133/427: More advanced :from sources, again.
Date: Tue, 13 Dec 2022 02:59:35 -0500 (EST)

branch: elpa/emacsql
commit 364c3cacb6a41345337ac612c666e41a43353c1c
Author: Christopher Wellons <wellons@nullprogram.com>
Commit: Christopher Wellons <wellons@nullprogram.com>

    More advanced :from sources, again.
---
 README.md        |  2 ++
 emacsql-tests.el | 10 ++++++++--
 emacsql.el       | 30 ++++++++++++++++++++----------
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index d936c94f92..65c61f7310 100644
--- a/README.md
+++ b/README.md
@@ -152,7 +152,9 @@ Provides `FROM`.
 ```el
 [... :from employees]
 [... :from [employees accounts]]
+[... :from [employees (accounts a)]]
 [... :from (:select ...)]
+[... :from [((:select ...) s1) ((:select ...) s2)]]
 ```
 
 #### :where `<expr>`
diff --git a/emacsql-tests.el b/emacsql-tests.el
index d659dcd804..ac622c12b9 100644
--- a/emacsql-tests.el
+++ b/emacsql-tests.el
@@ -69,7 +69,14 @@
     ([:select * :from employees :where (< salary 50000)] '()
      "SELECT * FROM employees WHERE salary < 50000;")
     ([:select * :from people :where (in name $1)] '([FOO BAR])
-     "SELECT * FROM people WHERE name IN ('FOO', 'BAR');")))
+     "SELECT * FROM people WHERE name IN ('FOO', 'BAR');")
+    ;; Sub queries
+    ([:select name :from (:select * :from $1)] '(people)
+     "SELECT name FROM (SELECT * FROM people);")
+    ([:select name :from [people (accounts a)]] '()
+     "SELECT name FROM people, accounts a;")
+    ([:select p:name :from [((:select * :from people) p)]] '()
+     "SELECT p.name FROM (SELECT * FROM people) p;")))
 
 (ert-deftest emacsql-create-table ()
   (emacsql-tests-with-queries
@@ -94,7 +101,6 @@
      "CREATE TABLE foo (a, b, c, UNIQUE (a, b, c));")
     ([:create-table foo ([a b] :check (< a b)) ] '()
      "CREATE TABLE foo (a, b, CHECK (a < b));")
-
     ([:drop-table $1] '(foo)
      "DROP TABLE foo;")))
 
diff --git a/emacsql.el b/emacsql.el
index c38af94b21..af2d0d7aea 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -395,7 +395,8 @@ definitions for return from a `emacsql-defexpander'."
      (cl-flet* ((var (thing kind) (emacsql--vars-var thing kind))
                 (combine (expanded) (emacsql--vars-combine expanded))
                 (expr (thing) (combine (emacsql--expr thing)))
-                (idents (thing) (combine (emacsql--idents thing))))
+                (idents (thing) (combine (emacsql--idents thing)))
+                (subsql (thing) (combine (emacsql-expand thing t))))
        (cons (concat ,prefix (progn ,@body)) emacsql--vars))))
 
 (defun emacsql--column-to-string (column)
@@ -504,10 +505,7 @@ definitions for return from a `emacsql-defexpander'."
                (1 (error "Wrong number of operands for %s" op))
                (2 (format "%s IN %s" (recur 0) (var (nth 1 args) :vector)))
                (otherwise
-                (let ((subsql (cl-coerce (cdr args) 'vector)))
-                  (format "%s IN %s"
-                          (recur 0)
-                          (combine (emacsql-expand subsql :sub)))))))))))))
+                (format "%s IN %s" (recur 0) (subsql (cdr args))))))))))))
 
 (defun emacsql--idents (idents)
   "Read in a vector of IDENTS identifiers, or just an single identifier."
@@ -532,13 +530,25 @@ definitions for return from a `emacsql-defexpander'."
         "*"
       (idents arg))))
 
-(emacsql-defexpander :from (table)
+(emacsql-defexpander :from (sources)
   "Expands to the FROM keyword."
   (emacsql-with-vars "FROM "
-    (cl-etypecase table
-      (vector (idents table))
-      (symbol (var table :identifier))
-      (list (combine (emacsql-expand table :subsql-p))))))
+    (cl-etypecase sources
+      (symbol (var sources :identifier))
+      (list (if (eq :select (car sources))
+                (subsql sources)
+              (cl-destructuring-bind (table alias) sources
+                (concat (var table :identifier) " " (var alias :identifier)))))
+      (vector (mapconcat (lambda (source)
+                           (cl-etypecase source
+                             (symbol (var source :identifier))
+                             (list
+                              (cl-destructuring-bind (table alias) source
+                                (concat (if (symbolp table)
+                                            (var table :identifier)
+                                          (subsql table))
+                                        " " (var alias :identifier))))))
+                         sources ", ")))))
 
 (emacsql-defexpander :replace ()
   (list "REPLACE"))



reply via email to

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