sql icon indicating copy to clipboard operation
sql copied to clipboard

Better way to do dynamic WHERE clauses? "apply"ing ScalarExprs to operators.

Open chuck-sys opened this issue 2 years ago • 0 comments

Let's say we have a table that looks like this:

CREATE TABLE media (
    id SERIAL PRIMARY KEY,
    title text,
    artist text,
    album text
);

And want to create a query that sometimes searches the fields title, artist, and album. So one query might look like:

SELECT * FROM media WHERE title LIKE "%someTitle%";

But others might look like:

SELECT * FROM media WHERE title LIKE "%someTitle%" AND album LIKE "%someAlbum%";

The way I figure out was to use ScalarExpr:INJECT like so:

;; make-media-single-condition: (list/c symbol? string?) -> scalar-expr-ast?
(define (make-media-single-condition condition)
  (match-let ([(list col val) condition])
    (scalar-expr-qq
      (like (Ident:AST ,(make-ident-ast col))
            (|| "%" (ScalarExpr:AST ,val) "%")))))

(scalar-expr-qq
  (ScalarExpr:INJECT
    ,(string-join
       (map
         (compose sql-ast->string make-media-single-condition)
         conditions)
       " AND ")))])))

Which is a bit hacky but gets the job done. Is there a way to apply the list of ScalarExpr to the and?

chuck-sys avatar Nov 27 '22 08:11 chuck-sys