Skip to content

Commit

Permalink
maybe going through structured types is nicer than string manipulation?
Browse files Browse the repository at this point in the history
  • Loading branch information
piranha committed May 9, 2024
1 parent 9a44570 commit daf050c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 14 deletions.
1 change: 1 addition & 0 deletions .dir-locals.el
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
(whitespace-line-column . 118)
(column-enforce-column . 118)
(clojure-docstring-fill-column . 118)
(clojure-indent-style . always-align)
(eval . (put-clojure-indent 'with-meta '(:form)))
(eval . (put-clojure-indent 'with-bindings* '(:form)))))
(markdown-mode . ((fill-column . 80)
Expand Down
43 changes: 35 additions & 8 deletions java/com/metabase/macaw/AstWalker.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,12 @@ public String toString() {
}
}

public enum QueryContext {
public interface QueueItem {
public String getKey();
public String getValue();
}

public enum QueryContext implements QueueItem {
DELETE,
ELSE,
FROM,
Expand All @@ -242,16 +247,38 @@ public enum QueryContext {
UPDATE,
WHERE;

public String toString() {
public String getKey() {
return "query";
}

public String getValue() {
return name().toUpperCase();
}
}

public class SomeContext implements QueueItem {
private String key;
private String value;

SomeContext(String key, String value) {
this.key = key;
this.value = value;
}

public String getKey() {
return this.key;
}

public String getValue() {
return this.value;
}
}

private static final String NOT_SUPPORTED_YET = "Not supported yet.";

private Acc acc;
private final EnumMap<CallbackKey, IFn> callbacks;
private final Deque<String> contextStack;
private final Deque<QueueItem> contextStack;

/**
* Construct a new walker with the given `callbacks`. The `callbacks` should be a (Clojure) map of CallbackKeys to
Expand All @@ -262,7 +289,7 @@ public String toString() {
public AstWalker(Map<CallbackKey, IFn> rawCallbacks, Acc val) {
this.acc = val;
this.callbacks = new EnumMap<>(rawCallbacks);
this.contextStack = new ArrayDeque<String>();
this.contextStack = new ArrayDeque<QueueItem>();
}

/**
Expand All @@ -278,11 +305,11 @@ public void invokeCallback(CallbackKey key, Object visitedItem) {
}

private void pushContext(QueryContext c) {
this.contextStack.push(c.toString());
this.contextStack.push(c);
}

private void pushContext(String s) {
this.contextStack.push(s);
private void pushContext(QueueItem item) {
this.contextStack.push(item);
}

// This is pure sugar, but it's nice to be symmetrical with pushContext
Expand Down Expand Up @@ -846,7 +873,7 @@ public void visit(SelectItem item) {
var alias = item.getAlias();
if (alias != null) {
// FIXME: this is absolutely a hack, what's the best way to get around it?
pushContext("AS " + alias.getName());
pushContext(new SomeContext("alias", alias.getName()));
}
item.getExpression().accept(this);
if (alias != null) {
Expand Down
31 changes: 25 additions & 6 deletions src/macaw/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[macaw.util :as u]
[macaw.walk :as mw])
(:import
(com.metabase.macaw AstWalker$QueueItem AstWalker$QueryContext)
(net.sf.jsqlparser.expression Alias)
(net.sf.jsqlparser.parser CCJSqlParserUtil)
(net.sf.jsqlparser.schema Column Table)
Expand All @@ -19,7 +20,10 @@
([key-name xf]
(fn item-conjer [results component context]
(update results key-name conj {:component (xf component)
:context (vec context)}))))
:context (mapv
(fn [^AstWalker$QueueItem x]
[(keyword (.getKey x)) (.getValue x)])
context)}))))

(defn- query->raw-components
[^Statement parsed-query]
Expand All @@ -35,6 +39,13 @@
:tables #{}
:table-wildcards #{}}))

(comment
(def p (parsed-query "SELECT cost FROM (SELECT amount AS cost FROM orders)"))
(query->raw-components p)
(query->components p)
(-> (query->raw-components p) :columns first :component (.getFullyQualifiedName true))
)

;;; tables

(defn- make-table [^Table t _ctx]
Expand All @@ -59,9 +70,9 @@

;;; columns

(defn- maybe-column-alias [ctx]
(when (some-> (first ctx) (str/starts-with? "AS "))
{:alias (subs (first ctx) 3)}))
(defn- maybe-column-alias [[maybe-alias :as _ctx]]
(when (= (first maybe-alias) :alias)
{:alias (second maybe-alias)}))

(defn- maybe-column-table [{:keys [alias->table name->table]} ^Column c]
(if-let [t (.getTable c)]
Expand All @@ -80,9 +91,17 @@

;;; get them together

(defn- only-query-context [ctx]
(into [] (comp (filter #(= (first %) :query))
(map second))
ctx))

(defn- update-components
[f components]
(map #(update % :component f (:context %)) components))
(map #(-> %
(update :component f (:context %))
(update :context only-query-context))
components))

(defn query->components
"Given a parsed query (i.e., a [subclass of] `Statement`) return a map with the elements found within it.
Expand All @@ -102,7 +121,7 @@
data {:alias->table alias-map
:name->table table-map}]
{:columns (into #{} (update-components (partial make-column data) columns))
:has-wildcard? (into #{} has-wildcard?)
:has-wildcard? (into #{} (update-components (fn [x & _args] x) has-wildcard?))
:mutation-commands (into #{} mutation-commands)
:tables (into #{} (vals table-map))
:table-wildcards (into #{} (update-components (partial resolve-table-name data) table-wildcards))}))
Expand Down

0 comments on commit daf050c

Please sign in to comment.