   (declare (indent 2))
   `(emacsql-add-expander ,keyword ,(length args) (lambda ,args ,@body)))
 
+(defun emacsql-sql-p (thing)
+  "Return non-nil if THING looks like a :select."
+  (and (sequencep thing)
+       (or (not (null (assoc (elt thing 0) emacsql-expanders)))
+           (emacsql-sql-p (elt thing 0)))))
+
+(defun emacsql-get-expander (keyword)
+  "Return the expander with arity for KEYWORD."
+  (if (emacsql-sql-p keyword)
+      (list 0 (lambda () (emacsql-expand keyword :subsql-p)))
+    (cdr (assoc keyword emacsql-expanders))))
+
 (defun emacsql-expand (sql &optional subsql-p)
   "Expand SQL into a SQL-consumable string, with variables."
   (let* ((cache emacsql-expander-cache)

        (cl-loop with items = (cl-coerce sql 'list)
                 while (not (null items))
                 for keyword = (pop items)
                 for (arity expander) = (cdr (assoc keyword emacsql-expanders))
                 when expander
                 collect (apply expander (cl-subseq items 0 arity)) into parts
                 else do (error "Unrecognized keyword %s" keyword)

  "Expand EXPR recursively."
  (emacsql-with-vars ""
    (cond
     ((emacsql-sql-p expr) (subsql expr))
     ((atom expr) (var expr :auto))
     ((cl-destructuring-bind (op . args) expr
         (cl-flet ((recur (n) (combine (emacsql--expr (nth n args)))))
