Closed peoplestom closed 10 months ago
I think you want this in package postmodern, not cl-postgres. (See first line of your s-sql-extensions.lisp file). Also confused about the references to postgres specific. All of postmodern is postgresql specific.
Yeah I should have properly reviewed it prior to opening the PR, sorry. It should be good to go now.
Does something like this accomplish what you want?
(defun analyze-option (option)
"Option must be a list of 1 or 2 members with the first member being a keyword of :buffer-usage-limit,
:verbose or :skip-locked. The second member (if it exists) and the first member is :verbose or :skip-locked
should be on of :on, :off, :true, :false, 0, 1,t, nil, \"true\" or \"false\". The check for the string
true or false is case insensitive. If the first member is :buffers-usage-limit, the second member should
be either a number or a string containing a number and a size parameter (e.g. kb, MB, GB, TB).
See https://www.postgresql.org/docs/current/sql-analyze.html for details."
(destructuring-bind (name value)
(if (= (length option) 2)
option
(list (car option) "TRUE"))
(append
(list (string-upcase (to-sql-name name nil t)))
(list " ")
(list (format nil "~:@(~a~)"
(cond ((and (eq name :buffer-usage-limit)
(or (numberp value)
(parse-integer value :junk-allowed t)))
(format nil "~a" value))
((and (or (eq name :verbose)
(eq name :skip-locked))
(or (eq value :off)
(eq value :false)
(eq value 0)
(eq value nil)
(equalp value "false")
(equalp value "off")))
"FALSE")
((and (or (eq name :verbose)
(eq name :skip-locked))
(or (eq value :on)
(eq value :true)
(eq value 1)
(eq value t)
(equalp value "true")
(equalp value "on")))
"TRUE")
(t (error (format nil "Invalid Analyze Option name ~a value ~a type ~a type-v ~a"
name value (type-of name) (type-of value))))))))))
(defun sql-expand-analyze-option (elts &optional (sep ", "))
"Expand a list of elements, adding a separator between them."
(setf elts elts)
(loop :for (elt . rest) :on elts
:append (analyze-option elt)
:if rest :collect sep))
(def-sql-op :analyze (&rest args)
(split-on-keywords ( (verbose - ?)(option * ?)(tables * ?))
args
`("ANALYZE "
,@(when verbose '("VERBOSE "))
,@(when option
(append '("(")
(sql-expand-analyze-option option)
'(") ")))
,@(sql-expand-list tables))))
;;; Tests
(is (equal (sql (:analyze :option (:verbose t) :tables (:t1 't1c1 't1c2) (:t2 't2c1 't2c)))
"ANALYZE (VERBOSE TRUE) t1(t1c1, t1c2), t2(t2c1, t2c)"))
(is (equal (sql (:analyze :option (:verbose 1) (:skip-locked 0) (:buffer-usage-limit "70MB") :tables (:t1 't1c1 't1c2) (:t2 't2c1 't2c)))
"ANALYZE (VERBOSE TRUE, SKIP_LOCKED FALSE, BUFFER_USAGE_LIMIT 70MB) t1(t1c1, t1c2), t2(t2c1, t2c)"))
(is (equal (sql (:analyze :option (:verbose :off) (:skip-locked :on) (:buffer-usage-limit "70MB") :tables (:t1 't1c1 't1c2) (:t2 't2c1 't2c)))
"ANALYZE (VERBOSE FALSE, SKIP_LOCKED TRUE, BUFFER_USAGE_LIMIT 70MB) t1(t1c1, t1c2), t2(t2c1, t2c)"))
(is (equal (sql (:analyze :verbose :tables (:t1 't1c1 't1c2) (:t2 't2c1 't2c2 't2c3)))
"ANALYZE VERBOSE t1(t1c1, t1c2), t2(t2c1, t2c2, t2c3)"))
(is (equal (sql (:analyze :verbose))
"ANALYZE VERBOSE "))
(s (equal (sql (:analyze))
"ANALYZE "))
(is (equal (sql (:analyze :option (:verbose t) (:skip-locked nil) (:buffer-usage-limit "70MB") :tables (:t1 't1c1 't1c2) (:t2 't2c1 't2c)))
"ANALYZE (VERBOSE TRUE, SKIP_LOCKED FALSE, BUFFER_USAGE_LIMIT 70MB) t1(t1c1, t1c2), t2(t2c1, t2c)"))
(is (equal (sql (:analyze :option (:verbose t) (:skip-locked nil) (:buffer-usage-limit "70MB") :tables (:t1 't1c1 't1c2)))
"ANALYZE (VERBOSE TRUE, SKIP_LOCKED FALSE, BUFFER_USAGE_LIMIT 70MB) t1(t1c1, t1c2)"))
(is (equal (sql (:analyze :option (:verbose t) (:skip-locked nil) (:buffer-usage-limit "70MB") :tables (:t1 't1c1 't1c2)))
"ANALYZE (VERBOSE TRUE, SKIP_LOCKED FALSE, BUFFER_USAGE_LIMIT 70MB) t1(t1c1, t1c2)"))
Yeah that works for me. Thanks for the help, I was stuck on how to support both the old verbose and the new options. All I changed was to ignore :verbose if we got :options.
I want to call analyze in my lisp code and I'd prefer to use s-sql as it keeps the name transformations etc consistent.