implement self-joins

This commit is contained in:
Jeremy Penner 2022-03-26 12:24:03 -04:00
parent c25cb5d292
commit 881943ed17

View file

@ -45,32 +45,34 @@
(table.insert list value)))
(fn Sqlog.reference-name [self analysis name]
(if (. self.rules name) (append-if-missing analysis.referenced-rules name)
(. self.tables name) (append-if-missing analysis.tables name)
(if (or (. self.rules name) (. self.tables name))
(do (table.insert analysis.tables name)
(length analysis.tables))
(error (.. "Unknown table / rule " name))))
(fn Sqlog.reference-variable [self analysis varname name icolumn]
(fn Sqlog.reference-variable [self analysis varname expr]
(match (. analysis.variable-mapping varname)
mapping (add-clause analysis [:= mapping [:column name icolumn]])
nil (do (tset analysis.variable-mapping varname [:column name icolumn])
mapping (add-clause analysis [:= mapping expr])
nil (do (tset analysis.variable-mapping varname expr)
(table.insert analysis.variables varname))))
(fn Sqlog.analyze-literal [self analysis literal]
(match literal
[:literal name params] (do (self:reference-name analysis name)
[:literal name params] (let [itable (self:reference-name analysis name)]
(each [icolumn value (ipairs params)]
(match value
[:var varname] (self:reference-variable analysis varname name icolumn)
[:const val] (add-clause analysis [:= [:column name icolumn] [:const val]])
[:var varname] (self:reference-variable analysis varname [:column itable icolumn])
[:const val] (add-clause analysis [:= [:column itable icolumn] [:const val]])
_ (error (.. "expected var or const, got " (fv value))))))
_ (error (.. "Expected literal but got " (fv literal)))))
(fn new-analysis [] {:referenced-rules [] :variables [] :variable-mapping {} :selection [] :clauses [] :tables [] :constants []})
(fn new-analysis [] {:variables [] :variable-mapping {} :selection [] :clauses [] :tables [] :constants []})
(fn Sqlog.gen-expr [self analysis expr]
(match expr
[:const val] (do (table.insert analysis.constants val) "?")
[:column name icolumn] (.. name "." (match (. self.tables name)
[:column itable icolumn] (.. "_t" itable "."
(match (. self.tables (. analysis.tables itable))
colnames (. colnames icolumn)
_ (.. "c" icolumn)))
[:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " name)
@ -86,7 +88,7 @@
(cat analysis.selection ", " #(self:gen-expr analysis $1))
"true")
" FROM "
(cat (lume.concat analysis.tables analysis.referenced-rules) " JOIN ")
(cat analysis.tables " JOIN " #(.. $1 " AS _t" $2))
(if (> (length analysis.clauses) 0)
(.. " WHERE " (cat analysis.clauses " AND " #(self:gen-expr analysis $1)))
"")))