fukamachi / sxql

An SQL generator for Common Lisp.
BSD 3-Clause "New" or "Revised" License
363 stars 31 forks source link

Proposal for user-defined operators/clauses #42

Open mtstickney opened 7 years ago

mtstickney commented 7 years ago

...or at least a step in that direction. This is closely related to #36 and #37, but I thought a new issue would be a better place to discuss it. The proposal:

  1. Turn sxql:make-op into a generic function that uses eql specializers on the first argument.
  2. Provide a default implementation that does what the current function does (i.e. searches the sxql.operator package[1]).
  3. Use a regular symbol in define-op instead of a keyword, and remove the interning.
  4. Apply the same treatment to sxql:make-clause if possible.

Defining a new operator would look like this:

(define-op (aref infix-op))

(defmethod make-op ((arg (eql :aref)) &rest args)
  (apply #'make-aref-op args))

(defmethod yield ((arg aref-op))
  ;; Not actually how you'd do it.
  (values (format nil "~A[~A]"
                      (yield (aref-op-left arg))
                      (yield (aref-op-right arg)))
               '()))

I don't think precedence of user-defined ops is an issue here, because we're generating this based the lisp tree which is already in the correct structure. I'm less sure about clauses, because e.g. the select statement sorts them, and user-defined clauses wouldn't have a way to specify order.

[1] Using find-symbol and not intern, of course; using intern will leave garbage symbols laying around if you call it with an op that doesn't exist.