sqlog compiler fixes and extensions

This commit is contained in:
Jeremy Penner 2022-04-20 23:22:38 -04:00
parent 6df7ec8c33
commit 6984389fbf
3 changed files with 33 additions and 23 deletions

View file

@ -161,7 +161,7 @@
(where [op] (. comparitors op)) (add-clause analysis literal) (where [op] (. comparitors op)) (add-clause analysis literal)
_ (error (.. "Expected literal or comparison but got " (fv literal))))) _ (error (.. "Expected literal or comparison but got " (fv literal)))))
(local infix-ops (collect [_ op (ipairs [:+ :- :* :/ :< :> :<= :>= := :|| :and :or])] op true)) (local infix-ops (collect [_ op (ipairs [:+ :- :* :/ :< :> :<= :>= := :|| :and :or :%])] op true))
(fn Compiler.gen-expr [self analysis expr] (fn Compiler.gen-expr [self analysis expr]
"Generates SQL code for a given expression tree." "Generates SQL code for a given expression tree."
(match expr (match expr
@ -172,7 +172,10 @@
_ (.. "c" icolumn))) _ (.. "c" icolumn)))
[:rowid itable] (.. "_t" itable "._rowid_") [:rowid itable] (.. "_t" itable "._rowid_")
[:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " (quoteid name)) [:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " (quoteid name))
[:set column subexpr] (.. column " = " (self:gen-expr analysis subexpr)) [:set column subexpr] (.. (quoteid column) " = " (self:gen-expr analysis subexpr))
[:case & clauses] (.. "CASE " (cat clauses " " #(self:gen-expr analysis $1)) " END")
[:when cmp result] (.. "WHEN " (self:gen-expr analysis cmp) " THEN " (self:gen-expr analysis result))
[:else result] (.. "ELSE " (self:gen-expr analysis result))
(where [:var name] (. analysis.variable-mapping name)) (self:gen-expr analysis (. analysis.variable-mapping name)) (where [:var name] (. analysis.variable-mapping name)) (self:gen-expr analysis (. analysis.variable-mapping name))
(where [op lhs rhs] (. infix-ops op)) (.. "(" (self:gen-expr analysis lhs) " " op " " (self:gen-expr analysis rhs) ")") (where [op lhs rhs] (. infix-ops op)) (.. "(" (self:gen-expr analysis lhs) " " op " " (self:gen-expr analysis rhs) ")")
[funcname & args] (.. funcname "(" (cat args ", " #(self:gen-expr analysis $1)) ")") [funcname & args] (.. funcname "(" (cat args ", " #(self:gen-expr analysis $1)) ")")

View file

@ -11,34 +11,40 @@
(fn Sqlog.deftable [self name ...] (self:execute (self.compiler:deftable name ...))) (fn Sqlog.deftable [self name ...] (self:execute (self.compiler:deftable name ...)))
(fn Sqlog.defrule [self head ...] (self.compiler:defrule head ...)) (fn Sqlog.defrule [self head ...] (self.compiler:defrule head ...))
(fn multi? [analysis] (and analysis (> (length analysis) 0)))
(fn Sqlog.compile-sql [self analysis] (fn Sqlog.compile-sql [self analysis]
(when (= analysis.stmt nil) (if (multi? analysis) (each [_ a (ipairs analysis)] (self:compile-sql a))
(let [stmt (sqlite.assert (sqlite.prepare self.db analysis.query))] (when (= analysis.stmt nil)
(sqlite.bind stmt analysis.constants) (let [stmt (sqlite.assert (sqlite.prepare self.db analysis.query))]
(set analysis.stmt stmt))) (sqlite.bind stmt analysis.constants)
(set analysis.stmt stmt))))
analysis) analysis)
(fn Sqlog.execute [self analysis ?collect-results] (fn Sqlog.execute [self analysis ?collect-results]
(self:compile-sql analysis) (if (multi? analysis) (icollect [_ a (ipairs analysis)] (self:execute a ?collect-results))
(sqlite.reset analysis.stmt) (do (print "running:" analysis.query (fv analysis.constants))
(if ?collect-results (self:compile-sql analysis)
(let [result []] (sqlite.reset analysis.stmt)
(while (= SQLITE_ROW (sqlite.step analysis.stmt)) (if ?collect-results
(table.insert result (collect [icol expr (ipairs analysis.selection)] (let [result []]
(match expr (while (= SQLITE_ROW (sqlite.step analysis.stmt))
[:as _ name] name (table.insert result (collect [icol expr (ipairs analysis.selection)]
_ icol) (match expr
(sqlite.column analysis.stmt icol)))) [:as _ name] name
result) _ icol)
(sqlite.step analysis.stmt))) (sqlite.column analysis.stmt icol))))
result)
(sqlite.step analysis.stmt)))))
(fn Sqlog.compile-action [self action] (fn Sqlog.compile-action [self action]
(self:compile-sql (self:compile-sql
(match action (match action
[:!+ & insert] (self.compiler:insert (table.unpack insert)) [:do & actions] (icollect [_ act (ipairs actions)] (self:compile-action act))
[:literal] (self.compiler:insert action) [:!+ & insert] (self.compiler:insert (table.unpack insert))
[:!- & delete] (self.compiler:delete (table.unpack delete)) [:literal] (self.compiler:insert action)
[:!= & update] (self.compiler:update (table.unpack update))))) [:!- & delete] (self.compiler:delete (table.unpack delete))
[:!= & update] (self.compiler:update (table.unpack update))
_ (error (.. "No such action " (fv action))))))
(fn Sqlog.compile-query [self ...] (self:compile-sql (self.compiler:query ...))) (fn Sqlog.compile-query [self ...] (self:compile-sql (self.compiler:query ...)))

View file

@ -1,4 +1,5 @@
(local Sqlog (require :sqlog)) (local Sqlog (require :sqlog))
(local {: show} (require :inspector.debug))
(import-macros {: $ : query : specify} :sqlog.macros) (import-macros {: $ : query : specify} :sqlog.macros)
(local s (Sqlog)) (local s (Sqlog))
@ -13,5 +14,5 @@
[parent :bob #(.. :fred :dy)] [parent :bob #(.. :fred :dy)]
[parent :fred :jim] [parent :fred :jim]
[parent :fred :betty]) [parent :fred :betty])
(pp (query s [ancestor :bob descendant gen])) (show (query s [ancestor (case descendant (when "bob jr" :bob) (else :jim)) descendant gen]))