diff --git a/modules/drivers/presto-jdbc/test/metabase/test/data/presto_jdbc.clj b/modules/drivers/presto-jdbc/test/metabase/test/data/presto_jdbc.clj
index 36abfdb311b4a61dc171a847f7ce2a4b0688aa31..61d7a710cc95245128fdcb55477b1bc62c6e37d1 100644
--- a/modules/drivers/presto-jdbc/test/metabase/test/data/presto_jdbc.clj
+++ b/modules/drivers/presto-jdbc/test/metabase/test/data/presto_jdbc.clj
@@ -163,7 +163,7 @@
   (testing "Make sure logic to strip out NOT NULL and PRIMARY KEY stuff works as expected"
     (let [db-def    (tx/get-dataset-definition defs/test-data)
           table-def (-> db-def :table-definitions second)]
-      (is (= "CREATE TABLE \"test_data\".\"default\".\"categories\" (\"id\" INTEGER, \"name\" VARCHAR) ;"
+      (is (= "CREATE TABLE \"test_data\".\"default\".\"test_data_categories\" (\"id\" INTEGER, \"name\" VARCHAR) ;"
              (sql.tx/create-table-sql :presto-jdbc db-def table-def))))))
 
 (defmethod ddl.i/format-name :presto-jdbc
diff --git a/src/metabase/lib/join.cljc b/src/metabase/lib/join.cljc
index 9c6abe6edc0e2d6d097de0c2291ce2223c06d1e2..27555533288214c20c80fd62e093a59e589d6667 100644
--- a/src/metabase/lib/join.cljc
+++ b/src/metabase/lib/join.cljc
@@ -198,8 +198,10 @@
    unique-name-fn :- fn?
    col            :- :map]
   (assoc col
-         :lib/source-column-alias  (:name col)
-         :lib/desired-column-alias (unique-name-fn (joined-field-desired-alias (:alias join) (:name col)))))
+         :lib/source-column-alias  ((some-fn :lib/source-column-alias :name) col)
+         :lib/desired-column-alias (unique-name-fn (joined-field-desired-alias
+                                                    (:alias join)
+                                                    ((some-fn :lib/source-column-alias :name) col)))))
 
 (defmethod lib.metadata.calculation/returned-columns-method :mbql/join
   [query
@@ -287,11 +289,11 @@
   "Create an MBQL join map from something that can conceptually be joined against. A `Table`? An MBQL or native query? A
   Saved Question? You should be able to join anything, and this should return a sensible MBQL join map."
   ([joinable]
-   (join-clause-method joinable))
+   (-> (join-clause-method joinable)
+       (u/assoc-default :fields :all)))
 
   ([joinable conditions]
    (-> (join-clause joinable)
-       (u/assoc-default :fields :all)
        (with-join-conditions conditions))))
 
 (mu/defn with-join-fields :- PartialJoin
diff --git a/src/metabase/lib/stage.cljc b/src/metabase/lib/stage.cljc
index 83fc4c573aabbf9ed73f4bcee372e45df0c90444..26c1266234928c0e50cf1223cec73c33a5efc834 100644
--- a/src/metabase/lib/stage.cljc
+++ b/src/metabase/lib/stage.cljc
@@ -85,8 +85,8 @@
    (for [breakout (lib.breakout/breakouts-metadata query stage-number)]
      (assoc breakout
             :lib/source               :source/breakouts
-            :lib/source-column-alias  (:name breakout)
-            :lib/desired-column-alias (unique-name-fn (:name breakout))))))
+            :lib/source-column-alias  ((some-fn :lib/source-column-alias :name) breakout)
+            :lib/desired-column-alias (unique-name-fn (lib.field/desired-alias query breakout))))))
 
 (mu/defn ^:private aggregations-columns :- [:maybe lib.metadata.calculation/ColumnsWithUniqueAliases]
   [query          :- ::lib.schema/query
@@ -99,6 +99,8 @@
             :lib/source-column-alias  (:name ag)
             :lib/desired-column-alias (unique-name-fn (:name ag))))))
 
+;;; TODO -- maybe the bulk of this logic should be moved into [[metabase.lib.field]], like we did for breakouts and
+;;; aggregations above.
 (mu/defn ^:private fields-columns :- [:maybe lib.metadata.calculation/ColumnsWithUniqueAliases]
   [query          :- ::lib.schema/query
    stage-number   :- :int
diff --git a/test/metabase/actions/test_util.clj b/test/metabase/actions/test_util.clj
index 09cc5621c2dc0ea23b62a4e81ca35f8fdfc96ef5..261e955b425ff03551c12a5336cf4b13d824f51a 100644
--- a/test/metabase/actions/test_util.clj
+++ b/test/metabase/actions/test_util.clj
@@ -2,7 +2,10 @@
   (:require
    [clojure.java.jdbc :as jdbc]
    [clojure.test :refer :all]
+   [metabase.driver :as driver]
+   [metabase.driver.ddl.interface :as ddl.i]
    [metabase.driver.sql-jdbc.connection :as sql-jdbc.conn]
+   [metabase.driver.sql.query-processor :as sql.qp]
    [metabase.http-client :as client]
    [metabase.models :refer [Action Card Database]]
    [metabase.models.action :as action]
@@ -14,6 +17,7 @@
    [metabase.test.data.users :as test.users]
    [metabase.test.initialize :as initialize]
    [metabase.test.util :as tu]
+   [metabase.util.honey-sql-2 :as h2x]
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
 
@@ -111,6 +115,23 @@
   [& body]
   `(do-with-dataset-definition (tx/dataset-definition ~(str (gensym))) (fn [] ~@body)))
 
+(defn- delete-categories-1-query []
+  (sql.qp/format-honeysql
+   2
+   (sql.qp/quote-style driver/*driver*)
+   {:delete-from [(h2x/identifier :table (ddl.i/format-name driver/*driver* "categories"))]
+    :where       [:=
+                  (h2x/identifier :field (ddl.i/format-name driver/*driver* "id"))
+                  [:inline 1]]}))
+
+(deftest ^:parallel delete-categories-1-query-test
+  (are [driver query] (= query
+                         (binding [driver/*driver* driver]
+                           (delete-categories-1-query)))
+    :h2       ["DELETE FROM \"CATEGORIES\" WHERE \"ID\" = 1"]
+    :postgres ["DELETE FROM \"categories\" WHERE \"id\" = 1"]
+    :mysql    ["DELETE FROM `categories` WHERE `id` = 1"]))
+
 (deftest with-actions-test-data-test
   (datasets/test-drivers (qp.test/normal-drivers-with-feature :actions/custom)
     (dotimes [i 2]
@@ -124,7 +145,7 @@
             (testing "delete row"
               (is (= [1]
                      (jdbc/execute! (sql-jdbc.conn/db->pooled-connection-spec (data/id))
-                                    "DELETE FROM CATEGORIES WHERE ID = 1;"))))
+                                    (delete-categories-1-query)))))
             (testing "after"
               (is (= [[74]]
                      (row-count))))))))))
diff --git a/test/metabase/lib/join_test.cljc b/test/metabase/lib/join_test.cljc
index f7ea077d2b4e55ef7f5e036724677bbaf824967c..709b713bbce0e4871db07530062e993bb9ec8a9a 100644
--- a/test/metabase/lib/join_test.cljc
+++ b/test/metabase/lib/join_test.cljc
@@ -55,6 +55,16 @@
                                              :args     [(lib/ref (meta/field-metadata :venues :category-id))
                                                         (lib/ref (meta/field-metadata :categories :id))]}]))))))
 
+(deftest ^:parallel join-clause-test
+  (testing "Should have :fields :all by default (#32419)"
+    (is (=? {:lib/type    :mbql/join
+             :stages      [{:lib/type     :mbql.stage/mbql
+                            :lib/options  {:lib/uuid string?}
+                            :source-table (meta/id :orders)}]
+             :lib/options {:lib/uuid string?}
+             :fields      :all}
+            (lib/join-clause (meta/table-metadata :orders))))))
+
 (deftest ^:parallel join-saved-question-test
   (is (=? {:lib/type :mbql/query
            :database (meta/id)
diff --git a/test/metabase/lib/stage_test.cljc b/test/metabase/lib/stage_test.cljc
index 3eb2a0033734dd243c5f566831fe551a9daab3ab..cc9fe272ecb5c1aff92d6583066ec55b3a2ee8bc 100644
--- a/test/metabase/lib/stage_test.cljc
+++ b/test/metabase/lib/stage_test.cljc
@@ -3,6 +3,7 @@
    [clojure.test :refer [deftest is testing]]
    [malli.core :as mc]
    [metabase.lib.core :as lib]
+   [metabase.lib.join :as lib.join]
    [metabase.lib.metadata.calculation :as lib.metadata.calculation]
    [metabase.lib.schema :as lib.schema]
    [metabase.lib.stage :as lib.stage]
@@ -10,8 +11,6 @@
    [metabase.lib.test-util :as lib.tu]
    #?@(:cljs ([metabase.test-runner.assert-exprs.approximately-equal]))))
 
-(comment lib/keep-me)
-
 #?(:cljs
    (comment metabase.test-runner.assert-exprs.approximately-equal/keep-me))
 
@@ -249,3 +248,100 @@
                 :lib/source :source/expressions}]
               (filter #(= (:name %) expr-name)
                       (lib.metadata.calculation/visible-columns query)))))))
+
+(defn- metadata-for-breakouts-from-joins-test-query
+  "A query against `ORDERS` with joins against `PRODUCTS` and `PEOPLE`, and breakouts on columns from both of those
+  joins."
+  []
+  (-> (lib/query meta/metadata-provider (meta/table-metadata :orders))
+      (lib/join (-> (lib/join-clause (meta/table-metadata :products))
+                    (lib/with-join-alias "P1")
+                    (lib/with-join-conditions [(lib/= (meta/field-metadata :orders :product-id)
+                                                      (-> (meta/field-metadata :products :id)
+                                                          (lib/with-join-alias "P1")))])))
+      (lib/join (-> (lib/join-clause (meta/table-metadata :people))
+                    (lib/with-join-alias "People")
+                    (lib/with-join-conditions [(lib/= (meta/field-metadata :orders :user-id)
+                                                      (-> (meta/field-metadata :people :id)
+                                                          (lib/with-join-alias "People")))])))
+      (lib/breakout (-> (meta/field-metadata :products :category)
+                        (lib/with-join-alias "P1")))
+      (lib/breakout (-> (meta/field-metadata :people :source)
+                        (lib/with-join-alias "People")))
+      (lib/aggregate (lib/count))))
+
+(deftest ^:parallel metadata-for-breakouts-from-joins-test
+  (testing "metadata for breakouts of joined columns should be calculated correctly (#29907)"
+    (let [query (metadata-for-breakouts-from-joins-test-query)]
+      (is (= [{:name                     "CATEGORY"
+               :lib/source-column-alias  "CATEGORY"
+               ::lib.join/join-alias     "P1"
+               :lib/desired-column-alias "P1__CATEGORY"}
+              {:name                     "SOURCE"
+               :lib/source-column-alias  "SOURCE"
+               ::lib.join/join-alias     "People"
+               :lib/desired-column-alias "People__SOURCE"}
+              {:name                     "count"
+               :lib/source-column-alias  "count"
+               :lib/desired-column-alias "count"}]
+             (map #(select-keys % [:name :lib/source-column-alias ::lib.join/join-alias :lib/desired-column-alias])
+                  (lib.metadata.calculation/returned-columns query)))))))
+
+(defn- metadata-for-breakouts-from-joins-test-query-2
+  "A query against `REVIEWS` joining `PRODUCTS`."
+  []
+  (-> (lib/query meta/metadata-provider (meta/table-metadata :reviews))
+      (lib/join (-> (lib/join-clause (meta/table-metadata :products))
+                    (lib/with-join-alias "P2")
+                    (lib/with-join-conditions [(lib/= (meta/field-metadata :reviews :product-id)
+                                                      (-> (meta/field-metadata :products :id)
+                                                          (lib/with-join-alias "P2")))])))
+      (lib/breakout (-> (meta/field-metadata :products :category)
+                        (lib/with-join-alias "P2")))
+      (lib/aggregate (lib/avg (meta/field-metadata :reviews :rating)))
+      lib/append-stage))
+
+(deftest ^:parallel metadata-for-breakouts-from-joins-test-2
+  (testing "metadata for breakouts of joined columns should be calculated correctly (#29907)"
+    (let [query (metadata-for-breakouts-from-joins-test-query-2)]
+      (is (= [{:name "CATEGORY", :lib/source-column-alias "P2__CATEGORY", :lib/desired-column-alias "P2__CATEGORY"}
+              {:name "avg", :lib/source-column-alias "avg", :lib/desired-column-alias "avg"}]
+             (map #(select-keys % [:name :lib/source-column-alias ::lib.join/join-alias :lib/desired-column-alias])
+                  (lib.metadata.calculation/returned-columns query)))))))
+
+(defn- metadata-for-breakouts-from-joins-from-previous-stage-test-query
+  "[[metadata-for-breakouts-from-joins-test-query]] but with an additional stage and a join
+  against [[metadata-for-breakouts-from-joins-test-query-2]]. This means there are two joins against `PRODUCTS`, one
+  from the first stage and one from the nested query in the join in the second stage."
+  []
+  (-> (metadata-for-breakouts-from-joins-test-query)
+      lib/append-stage
+      (lib/join (-> (lib/join-clause (metadata-for-breakouts-from-joins-test-query-2))
+                    (lib/with-join-alias "Q2")
+                    (lib/with-join-conditions [(lib/= (-> (meta/field-metadata :products :category)
+                                                          (lib/with-join-alias "P1"))
+                                                      (-> (meta/field-metadata :products :category)
+                                                          (lib/with-join-alias "Q2")))])))))
+
+(deftest ^:parallel metadata-for-breakouts-from-joins-from-previous-stage-test
+  (testing "metadata for breakouts of columns from join in previous stage should be calculated correctly (#29907)"
+    (let [query (metadata-for-breakouts-from-joins-from-previous-stage-test-query)]
+      (is (= [{:name                     "CATEGORY"
+               :lib/source-column-alias  "P1__CATEGORY"
+               :lib/desired-column-alias "P1__CATEGORY"}
+              {:name                     "SOURCE"
+               :lib/source-column-alias  "People__SOURCE"
+               :lib/desired-column-alias "People__SOURCE"}
+              {:name                     "count"
+               :lib/source-column-alias  "count"
+               :lib/desired-column-alias "count"}
+              {:name                     "CATEGORY"
+               :lib/source-column-alias  "P2__CATEGORY"
+               ::lib.join/join-alias     "Q2"
+               :lib/desired-column-alias "Q2__P2__CATEGORY"}
+              {:name                     "avg"
+               :lib/source-column-alias  "avg"
+               ::lib.join/join-alias     "Q2"
+               :lib/desired-column-alias "Q2__avg"}]
+             (map #(select-keys % [:name :lib/source-column-alias ::lib.join/join-alias :lib/desired-column-alias])
+                  (lib.metadata.calculation/returned-columns query)))))))
diff --git a/test/metabase/query_processor/middleware/constraints_test.clj b/test/metabase/query_processor/middleware/constraints_test.clj
index 089c0b0bd90831ca2262bfd3b538770a1bfb7303..0326066fa5e02690607f53d779e2ebab1da2d051 100644
--- a/test/metabase/query_processor/middleware/constraints_test.clj
+++ b/test/metabase/query_processor/middleware/constraints_test.clj
@@ -7,12 +7,12 @@
 (defn- add-default-userland-constraints [query]
   (:pre (mt/test-qp-middleware qp.constraints/add-default-userland-constraints query)))
 
-(deftest no-op-without-middleware-options-test
+(deftest ^:parallel no-op-without-middleware-options-test
   (testing "don't do anything to queries without [:middleware :add-default-userland-constraints?] set"
     (is (= {}
            (add-default-userland-constraints {})))))
 
-(deftest add-constraints-test
+(deftest ^:parallel add-constraints-test
   (testing "if it is *truthy* add the constraints"
     (is (= {:middleware  {:add-default-userland-constraints? true},
             :constraints {:max-results           @#'qp.constraints/max-results
@@ -20,13 +20,13 @@
            (add-default-userland-constraints
             {:middleware {:add-default-userland-constraints? true}})))))
 
-(deftest no-op-if-option-is-false-test
+(deftest ^:parallel no-op-if-option-is-false-test
   (testing "don't do anything if it's not truthy"
     (is (= {:middleware {:add-default-userland-constraints? false}}
            (add-default-userland-constraints
             {:middleware {:add-default-userland-constraints? false}})))))
 
-(deftest dont-overwrite-existing-constraints-test
+(deftest ^:parallel dont-overwrite-existing-constraints-test
   (testing "if it already has constraints, don't overwrite those!"
     (is (= {:middleware  {:add-default-userland-constraints? true}
             :constraints {:max-results           @#'qp.constraints/max-results
@@ -35,7 +35,7 @@
             {:constraints {:max-results-bare-rows 1}
              :middleware  {:add-default-userland-constraints? true}})))))
 
-(deftest max-results-bare-rows-should-be-less-than-max-results-test
+(deftest ^:parallel max-results-bare-rows-should-be-less-than-max-results-test
   (testing "if you specify just `:max-results` it should make sure `:max-results-bare-rows` is <= `:max-results`"
     (is (= {:middleware  {:add-default-userland-constraints? true}
             :constraints {:max-results           5
diff --git a/test/metabase/query_processor/middleware/limit_test.clj b/test/metabase/query_processor/middleware/limit_test.clj
index 6ff1ecb545e26eaf3a5d8ca8744464e82f336d1c..631e9c0d67538f0492e9731b541f1f7defec8b5c 100644
--- a/test/metabase/query_processor/middleware/limit_test.clj
+++ b/test/metabase/query_processor/middleware/limit_test.clj
@@ -20,7 +20,7 @@
     (is (= test-max-results
            (-> (limit {:type :native}) mt/rows count)))))
 
-(deftest disable-max-results-test
+(deftest ^:parallel disable-max-results-test
   (testing "Apply `absolute-max-results` limit in the default case"
     (let [query {:type :query
                  :query {}}]
diff --git a/test/metabase/test_runner.clj b/test/metabase/test_runner.clj
index 698c44e6fc5d622b677e7c865e48f6bdba22bcf5..9b2e1e31223d0a82202bfe31d5a5b6cd0ab528f0 100644
--- a/test/metabase/test_runner.clj
+++ b/test/metabase/test_runner.clj
@@ -84,7 +84,7 @@
    "test_resources"])
 
 (defn- default-options []
-  {:namespace-pattern   #"^metabase.*test$"
+  {:namespace-pattern   #"^metabase.*"
    :exclude-directories excluded-directories
    :test-warn-time      1500})