Function: emacsql--*expr

emacsql--*expr is a byte-compiled function defined in emacsql-compiler.el.

Signature

(emacsql--*expr EXPR &optional PARENT-PRECEDENCE-VALUE)

Documentation

Expand EXPR recursively.

Source Code

;; Defined in ~/.emacs.d/elpa/emacsql-20261001.1544/emacsql-compiler.el
(defun emacsql--*expr (expr &optional parent-precedence-value)
  "Expand EXPR recursively."
  (emacsql-with-params ""
    (cond
     ((emacsql-sql-p expr) (subsql expr))
     ((vectorp expr) (svector expr))
     ((atom expr) (param expr))
     ((cl-destructuring-bind (op . args) expr
        (cl-multiple-value-bind (format-string precedence-value)
            (emacsql--get-op-info op
                                  (length args)
                                  (or parent-precedence-value 0))
          (cl-flet ((recur (n)
                      (combine (emacsql--*expr (nth n args)
                                               (or precedence-value 0))))
                    (nops (op)
                      (emacsql-error "Wrong number of operands for %s" op)))
            (cl-case op
              ;; Special cases <= >=
              ((<= >=)
               (cl-case (length args)
                 (2 (format format-string (recur 0) (recur 1)))
                 (3 (format (if (>= (or parent-precedence-value 0)
                                    precedence-value)
                                "(%s BETWEEN %s AND %s)"
                              "%s BETWEEN %s AND %s")
                            (recur 1)
                            (recur (if (eq op '>=) 2 0))
                            (recur (if (eq op '>=) 0 2))))
                 (otherwise (nops op))))
              ;; enforce second argument to be a character
              ((escape)
               (let ((second-arg (cadr args)))
                 (cond
                  ((not (= 2 (length args))) (nops op))
                  ((not (characterp second-arg))
                   (emacsql-error
                    "Second operand of escape has to be a character, got %s"
                    second-arg))
                  (t (format format-string
                             (recur 0)
                             (emacsql-quote-character second-arg))))))
              ;; Ordering
              ((asc desc)
               (format "%s %s" (recur 0) (upcase (symbol-name op))))
              ;; Special case quote
              ((quote) (let ((arg (nth 0 args)))
                         (if (stringp arg)
                             (raw arg)
                           (scalar arg))))
              ;; Special case funcall
              ((funcall)
               (format "%s(%s)" (recur 0)
                       (cond
                        ((and (= 2 (length args))
                              (eq '* (nth 1 args)))
                         "*")
                        ((and (= 3 (length args))
                              (eq :distinct (nth 1 args))
                              (format "DISTINCT %s" (recur 2))))
                        ((mapconcat
                          #'recur (cl-loop for i from 1 below (length args)
                                           collect i)
                          ", ")))))
              ;; Guess
              (otherwise
               (let ((arg-indices (cl-loop for i from 0 below (length args) collect i)))
                 (if format-string
                     (apply #'format format-string (mapcar #'recur arg-indices))
                   (mapconcat
                    #'recur (cl-loop for i from 0 below (length args) collect i)
                    (format " %s " (upcase (symbol-name op)))))))))))))))