Compare commits

...

3 Commits

Author SHA1 Message Date
Alexander Polyankin
2e88fa605c Pass query info 2025-06-04 09:54:52 -04:00
Alexander Polyankin
fc45b383ce Pass query info 2025-06-04 09:54:52 -04:00
Alexander Polyankin
eb73b03bd7 Pass query info 2025-06-04 09:54:52 -04:00
5 changed files with 34 additions and 28 deletions

View File

@@ -1577,13 +1577,13 @@
(simple-mbql->native inner-query)))
(defn- preprocess
[inner-query]
(add/add-alias-info inner-query))
[inner-query query-info]
(add/add-alias-info inner-query query-info))
(defn mbql->native
"Compile an MBQL query."
[query]
(let [query (update query :query preprocess)]
[{query-info :info, :as query}]
(let [query (update query :query #(preprocess % query-info))]
(binding [*query* query
*next-alias-index* (volatile! 0)]
(let [source-table-name (if-let [source-table-id (mbql.u/query->source-table-id query)]

View File

@@ -782,9 +782,9 @@
(fix-order-bys (assoc m :limit limit/absolute-max-results)))))
(defmethod sql.qp/preprocess :sqlserver
[driver inner-query]
[driver inner-query query-info]
(let [parent-method (get-method sql.qp/preprocess :sql)]
(fix-order-bys (parent-method driver inner-query))))
(fix-order-bys (parent-method driver inner-query query-info))))
;; In order to support certain native queries that might return results at the end, we have to use only prepared
;; statements (see #9940)

View File

@@ -1984,7 +1984,7 @@
"Do miscellaneous transformations to the MBQL before compiling the query. These changes are idempotent, so it is safe
to use this function in your own implementations of [[driver/mbql->native]], if you want to apply changes to the
same version of the query that we will ultimately be compiling."
{:changelog-test/ignore true, :arglists '([driver inner-query]), :added "0.42.0"}
{:changelog-test/ignore true, :arglists '([driver inner-query query-info]), :added "0.42.0"}
driver/dispatch-on-initialized-driver
:hierarchy #'driver/hierarchy)
@@ -2018,18 +2018,18 @@
nest-breakouts-in-queries-with-window-fn-aggregations))
(defmethod preprocess :sql
[_driver inner-query]
[_driver inner-query query-info]
(-> inner-query
maybe-nest-breakouts-in-queries-with-window-fn-aggregations
add/add-alias-info
nest-query/nest-expressions))
(add/add-alias-info query-info)
(nest-query/nest-expressions query-info)))
(mu/defn mbql->honeysql :- [:or :map [:tuple [:= :inline] :map]]
"Build the HoneySQL form we will compile to SQL and execute."
[driver :- :keyword
{inner-query :query} :- :map]
{inner-query :query, query-info :info} :- :map]
(binding [driver/*driver* driver]
(let [inner-query (preprocess driver inner-query)]
(let [inner-query (preprocess driver inner-query query-info)]
(log/tracef "Compiling MBQL query\n%s" (u/pprint-to-str 'magenta inner-query))
(u/prog1 (apply-clauses driver {} inner-query)
(log/debugf "\nHoneySQL Form: %s\n%s" (u/emoji "🍯") (u/pprint-to-str 'cyan <>))

View File

@@ -218,6 +218,10 @@
(when (#{:expression :field} tag)
(= desired-alias field-name)))
all-exports)
(m/find-first (fn [[tag _id-or-name {::keys [original-desired-alias], :as _opts} :as _ref]]
(when (#{:expression :field} tag)
(= original-desired-alias field-name)))
all-exports)
;; Expressions by exact name.
(m/find-first (fn [[_ expression-name :as _expression-clause]]
(= expression-name field-name))
@@ -408,19 +412,21 @@
:else field-name))
(defmulti ^:private clause-alias-info
{:arglists '([inner-query unique-alias-fn clause])}
(fn [_ _ [clause-type]]
{:arglists '([inner-query query-info unique-alias-fn clause])}
(fn [_ _ _ [clause-type]]
clause-type))
(defmethod clause-alias-info :field
[inner-query unique-alias-fn field-clause]
(let [expensive-info (expensive-field-info inner-query field-clause)]
[inner-query {:alias/keys [escaped->original], :as _query-info} unique-alias-fn field-clause]
(let [expensive-info (expensive-field-info inner-query field-clause)
original-field-clause (mbql.u/update-field-options field-clause update :join-alias #(get escaped->original % %))]
(merge {::source-table (field-source-table-alias inner-query field-clause)
::source-alias (field-source-alias inner-query field-clause expensive-info)}
(when-let [nfc-path (:nfc-path expensive-info)]
{::nfc-path nfc-path})
(when-let [position (clause->position inner-query field-clause)]
{::desired-alias (unique-alias-fn position (field-desired-alias inner-query field-clause expensive-info))
::original-desired-alias (field-desired-alias inner-query original-field-clause expensive-info)
::position position}))))
(defmulti ^:private aggregation-name
@@ -447,7 +453,7 @@
(:name opts))
(defmethod clause-alias-info :aggregation
[{aggregations :aggregation, :as inner-query} unique-alias-fn [_ index _opts :as ag-ref-clause]]
[{aggregations :aggregation, :as inner-query} _query-info unique-alias-fn [_ index _opts :as ag-ref-clause]]
(let [position (clause->position inner-query ag-ref-clause)]
;; an aggregation is ALWAYS returned, so it HAS to have a `position`. If it does not, the aggregation reference
;; is busted.
@@ -461,7 +467,7 @@
::position position})))
(defmethod clause-alias-info :expression
[inner-query unique-alias-fn [_ expression-name :as expression-ref-clause]]
[inner-query _query-info unique-alias-fn [_ expression-name :as expression-ref-clause]]
(when-let [position (clause->position inner-query expression-ref-clause)]
{::desired-alias (unique-alias-fn position expression-name)
::position position}))
@@ -501,7 +507,7 @@
(add-info-to-aggregation-definition inner-query unique-alias-fn aggregation i)))
aggregations)))))
(defn- add-alias-info* [inner-query]
(defn- add-alias-info* [inner-query query-info]
(assert (not (:strategy inner-query)) "add-alias-info* should not be called on a join") ; not user-facing
(let [unique-alias-fn (make-unique-alias-fn)]
(-> (lib.util.match/replace inner-query
@@ -511,7 +517,7 @@
&match
#{:field :aggregation :expression}
(mbql.u/update-field-options &match merge (clause-alias-info inner-query unique-alias-fn &match)))
(mbql.u/update-field-options &match merge (clause-alias-info inner-query query-info unique-alias-fn &match)))
(add-info-to-aggregation-definitions unique-alias-fn))))
(defn add-alias-info
@@ -542,12 +548,12 @@
If this clause is 'selected', this is the position the clause will appear in the results (i.e. the corresponding
column index)."
[query-or-inner-query]
[query-or-inner-query query-info]
(walk/postwalk
(fn [form]
(if (and (map? form)
((some-fn :source-query :source-table) form)
(not (:strategy form)))
(vary-meta (add-alias-info* form) assoc ::transformed true)
(vary-meta (add-alias-info* form query-info) assoc ::transformed true)
form))
query-or-inner-query))

View File

@@ -110,7 +110,7 @@
(filterv used?* fields))]
(update source :fields remove-unused))))
(defn- nest-source [inner-query]
(defn- nest-source [inner-query query-info]
(let [filter-clause (:filter inner-query)
keep-filter? (nil? (lib.util.match/match-one filter-clause :expression))
source (as-> (select-keys inner-query [:source-table :source-query :source-metadata :joins :expressions :expression-idents]) source
@@ -124,7 +124,7 @@
:type :query
:query source}))
(add-all-fields source)
(add/add-alias-info source)
(add/add-alias-info source query-info)
(:query source)
(dissoc source :limit)
(qp.middleware.resolve-joins/append-join-fields-to-fields source (joined-fields inner-query))
@@ -233,12 +233,12 @@
"Pushes the `:source-table`/`:source-query`, `:expressions`, and `:joins` in the top-level of the query into a
`:source-query` and updates `:expression` references and `:field` clauses with `:join-alias`es accordingly. See
tests for examples. This is used by the SQL QP to make sure expressions happen in a subselect."
[inner-query]
[inner-query query-info]
(let [{:keys [expressions expression-idents]
:as inner-query} (m/update-existing inner-query :source-query nest-expressions)]
:as inner-query} (m/update-existing inner-query :source-query #(nest-expressions % query-info))]
(if-not (should-nest-expressions? inner-query)
inner-query
(let [{:keys [source-query], :as inner-query} (nest-source inner-query)
(let [{:keys [source-query], :as inner-query} (nest-source inner-query query-info)
inner-query (rewrite-fields-and-expressions inner-query)
source-query (assoc source-query
:expressions expressions
@@ -246,4 +246,4 @@
(-> inner-query
(dissoc :source-query :expressions :expression-idents)
(assoc :source-query source-query)
add/add-alias-info)))))
(add/add-alias-info query-info))))))