Implement update

This commit is contained in:
Jeremy Penner 2022-03-27 16:49:22 -04:00
parent ea5da24813
commit 0cdcd865c5
2 changed files with 27 additions and 4 deletions

View file

@ -68,8 +68,8 @@
; update: ; update:
; (!~ [q (+ x 1)] [q x]) -> UPDATE q SET c1 = q.c1 + 1 ; (!~ [q (+ x 1)] [q x]) -> UPDATE q SET c1 = q.c1 + 1
; (!~ [p (+ x 1) _] [p x 3]) -> UPDATE p SET c1 = p.c1 + 1 WHERE p.c2 = 3 ; (!~ [p (+ x 1) _] [p x 3]) -> UPDATE p SET c1 = p.c1 + 1 WHERE p.c2 = 3
; (!~ [p (+ x 1) _] [q x]) -> UPDATE p SET c1 = q.c1 + 1 FROM q -- this is madness but might be valid sql?? if q only has one row ; invalid update:
; (!~ [p (+ x 1) _] [q x]) -> UPDATE p SET c1 = q.c1 + 1 FROM q -- this is valid sql, but it's madness - enforce the first query clause matches table
(fn Sqlog.new [self] (fn Sqlog.new [self]
(set self.tables {}) (set self.tables {})
@ -141,8 +141,9 @@
(match (. self.tables (. analysis.tables itable)) (match (. self.tables (. analysis.tables itable))
colnames (. colnames icolumn) colnames (. colnames icolumn)
_ (.. "c" icolumn))) _ (.. "c" icolumn)))
[:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " name)
[:rowid itable] (.. "_t" itable "._rowid_") [:rowid itable] (.. "_t" itable "._rowid_")
[:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " name)
[:set column subexpr] (.. column " = " (self:gen-expr analysis subexpr))
(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) ")")
_ (error (.. "Unrecognized expression " (fv expr))))) _ (error (.. "Unrecognized expression " (fv expr)))))
@ -188,6 +189,16 @@
(.. " WHERE " (cat analysis.clauses " AND " #(self:gen-expr analysis $1))) (.. " WHERE " (cat analysis.clauses " AND " #(self:gen-expr analysis $1)))
""))) "")))
(fn Sqlog.gen-update [self analysis]
(.. "UPDATE " (. analysis.tables 1) " AS _t1 SET "
(cat analysis.selection ", " #(self:gen-expr analysis $1))
(if (>= (length analysis.tables) 2)
(.. " FROM " (cat (lume.slice analysis.tables 2) " JOIN " #(.. $1 " AS _t" (+ $2 1))))
"")
(if (> (length analysis.clauses) 0)
(.. " WHERE " (cat analysis.clauses " AND " #(self:gen-expr analysis $1)))
"")))
(fn Sqlog.query [self ...] (fn Sqlog.query [self ...]
(let [analysis (new-analysis)] (let [analysis (new-analysis)]
(each [_ literal (ipairs [...])] (self:analyze-literal analysis literal)) (each [_ literal (ipairs [...])] (self:analyze-literal analysis literal))
@ -218,5 +229,17 @@
analysis.constants]) analysis.constants])
_ (error (.. "Expected literal, got " (fv head))))) _ (error (.. "Expected literal, got " (fv head)))))
(fn Sqlog.update [self newhead head ...]
(match [newhead head]
[[:literal name params] [:literal name]]
(let [analysis (new-analysis)
columns (. self.tables name)]
(each [_ literal (ipairs [head ...])] (self:analyze-literal analysis literal))
(set analysis.selection (icollect [icolumn param (ipairs params)]
(match param
[:var :_] nil
expr [:set (. columns icolumn) expr])))
[(.. (self:gen-with-rules analysis) (self:gen-update analysis)) analysis.constants])))
Sqlog Sqlog

View file

@ -10,4 +10,4 @@
([generation name (|| name " iii") 3] [ancestor name (|| name " iii")]) ([generation name (|| name " iii") 3] [ancestor name (|| name " iii")])
([ancestor x y 1] [parent x y]) ([ancestor x y 1] [parent x y])
([ancestor x y (+ gen 1)] [parent x z] [ancestor z y gen])) ([ancestor x y (+ gen 1)] [parent x z] [ancestor z y gen]))
(pp (delete s [p 1 x] [q x])) (pp (update s [p _ (+ y 1)] [p x y] [q x]))