diff --git a/src/metabase/api/database.clj b/src/metabase/api/database.clj
index 8218d560b922fb618db292facd3bc3351b433f9c..67d838539988747b014182b3f3157b72f1c6d4ba 100644
--- a/src/metabase/api/database.clj
+++ b/src/metabase/api/database.clj
@@ -189,10 +189,25 @@
   [db]
   (assoc db :schedules (expanded-schedules db)))
 
+(defn- get-database-hydrate-include
+  "If URL param `?include=` was passed to `GET /api/database/:id`, hydrate the Database appropriately."
+  [db include]
+  (if-not include
+    db
+    (-> (hydrate db (case include
+                      "tables"        :tables
+                      "tables.fields" [:tables [:fields [:target :has_field_values] :has_field_values]]))
+        (update :tables (partial filter mi/can-read?)))))
+
 (api/defendpoint GET "/:id"
-  "Get `Database` with ID."
-  [id]
-  (add-expanded-schedules (api/read-check Database id)))
+  "Get a single Database with `id`. Optionally pass `?include=tables` or `?include=tables.fields` to include the Tables
+  belonging to this database, or the Tables and Fields, respectively."
+  [id include]
+  {include (s/maybe (s/enum "tables" "tables.fields"))}
+  (println "include:" include) ; NOCOMMIT
+  (-> (api/read-check Database id)
+      add-expanded-schedules
+      (get-database-hydrate-include include)))
 
 
 ;;; ----------------------------------------- GET /api/database/:id/metadata -----------------------------------------
diff --git a/test/metabase/api/database_test.clj b/test/metabase/api/database_test.clj
index 1d67d41110a19c14a1c7aba1e78544d408eca7f9..7ad8c8437e85dad681a7b753420a5f11e436b0df 100644
--- a/test/metabase/api/database_test.clj
+++ b/test/metabase/api/database_test.clj
@@ -22,7 +22,9 @@
             [metabase.test.fixtures :as fixtures]
             [metabase.util.schema :as su]
             [schema.core :as s]
-            [toucan.db :as db]))
+            [toucan
+             [db :as db]
+             [hydrate :as hydrate]]))
 
 (use-fixtures :once (fixtures/initialize :plugins))
 
@@ -63,11 +65,70 @@
   ([{driver :engine, :as db}]
    (merge
     default-db-details
-    (select-keys db [:created_at :id :details :updated_at :timezone])
-    {:features (map u/qualified-name (driver.u/features driver))})))
+    (select-keys db [:created_at :id :details :updated_at :timezone :name])
+    {:engine   (u/qualified-name (:engine db))
+     :features (map u/qualified-name (driver.u/features driver))})))
 
+(def ^:private default-table-details
+  {:description             nil
+   :entity_name             nil
+   :entity_type             "entity/GenericTable"
+   :caveats                 nil
+   :points_of_interest      nil
+   :visibility_type         nil
+   :active                  true
+   :show_in_getting_started false})
+
+(defn- table-details [table]
+  (-> default-table-details
+      (merge
+       (select-keys table [:active :created_at :db_id :description :display_name :entity_name :entity_type :fields_hash
+                           :id :name :rows :schema :updated_at :visibility_type]))
+      (update :entity_type (fn [entity-type]
+                             (when entity-type
+                               (str "entity/" (name entity-type)))))
+      (update :visibility_type #(when % (name %)))))
+
+(defn- expected-tables [db-or-id]
+  (map table-details (db/select Table
+                       :db_id (u/get-id db-or-id), :active true
+                       {:order-by [[:%lower.schema :asc] [:%lower.display_name :asc]]})))
+
+(def ^:private default-field-details
+  {:description        nil
+   :caveats            nil
+   :points_of_interest nil
+   :active             true
+   :position           0
+   :target             nil
+   :preview_display    true
+   :parent_id          nil
+   :settings           nil})
+
+(defn- field-details [field]
+  (merge
+   default-field-details
+   (select-keys
+    field
+    [:updated_at :id :created_at :last_analyzed :fingerprint :fingerprint_version :fk_target_field_id :position])))
+
+(deftest databases-list-test
+  (testing "GET /api/database"
+    (testing "Test that we can get all the DBs (ordered by name, then driver)"
+      (testing "Database details *should not* come back for Rasta since she's not a superuser"
+        (let [expected-keys (-> (into #{:features :native_permissions} (keys (Database (mt/id))))
+                                (disj :details))]
+          (doseq [db ((mt/user->client :rasta) :get 200 "database")]
+            (testing (format "Database %s %d %s" (:engine db) (u/get-id db) (pr-str (:name db)))
+              (is (= expected-keys
+                     (set (keys db)))))))))
 
-;; # DB LIFECYCLE ENDPOINTS
+    (testing "?include_tables=true"
+      (mt/with-temp Database [{db-id :id, db-name :name} {:engine (u/qualified-name ::test-driver)}]
+        (doseq [db ((mt/user->client :rasta) :get 200 "database" :include_tables true)]
+          (testing (format "Database %s %d %s" (:engine db) (u/get-id db) (pr-str (:name db)))
+            (is (= (expected-tables db)
+                   (:tables db)))))))))
 
 (defn- add-schedules [db]
   (assoc db :schedules {:cache_field_values {:schedule_day   nil
@@ -79,18 +140,45 @@
                                              :schedule_hour  nil
                                              :schedule_type  "hourly"}}))
 
-;; ## GET /api/database/:id
-
-(deftest regular-users--should-not--see-db-details
-  (is (= (add-schedules (dissoc (db-details) :details))
-         ((mt/user->client :rasta) :get 200 (format "database/%d" (mt/id))))))
-
-(deftest superusers--should--see-db-details
-  (is (= (add-schedules (db-details))
-         ((mt/user->client :crowberto) :get 200 (format "database/%d" (mt/id))))))
-
+(deftest get-database-test
+  (testing "GET /api/database/:id"
+    (testing "DB details visibility"
+      (testing "Regular users should not see DB details"
+        (is (= (add-schedules (dissoc (db-details) :details))
+               ((mt/user->client :rasta) :get 200 (format "database/%d" (mt/id))))))
+
+      (testing "Superusers should see DB details"
+        (is (= (add-schedules (db-details))
+               ((mt/user->client :crowberto) :get 200 (format "database/%d" (mt/id)))))))
+
+    (mt/with-temp* [Database [db {:name "My DB", :engine ::test-driver}]
+                    Table    [t1 {:name "Table 1", :db_id (:id db)}]
+                    Table    [t2 {:name "Table 2", :db_id (:id db)}]
+                    Field    [f1 {:name "Field 1.1", :table_id (:id t1)}]
+                    Field    [f2 {:name "Field 2.1", :table_id (:id t2)}]
+                    Field    [f3 {:name "Field 2.2", :table_id (:id t2)}]]
+      (testing "`?include=tables` -- should be able to include Tables"
+        (is (= {:tables [(table-details t1)
+                         (table-details t2)]}
+               (select-keys ((mt/user->client :lucky) :get 200 (format "database/%d?include=tables" (:id db)))
+                            [:tables]))))
+
+      (testing "`?include=tables.fields` -- should be able to include Tables and Fields"
+        (letfn [(field-details* [field]
+                  (assoc (into {} (hydrate/hydrate field [:target :has_field_values] :has_field_values))
+                         :base_type        "type/Text"
+                         :visibility_type  "normal"
+                         :has_field_values "search"))]
+          (is (= (-> {:tables [(assoc (table-details t1) :fields [(field-details* f1)])
+                               (assoc (table-details t2) :fields [(field-details* f2)
+                                                                  (field-details* f3)])]})
+                 (select-keys ((mt/user->client :lucky) :get 200 (format "database/%d?include=tables.fields" (:id db)))
+                              [:tables]))))))
+
+    (testing "Invalid `?include` should return an error"
+      (is (= {:errors {:include "value may be nil, or if non-nil, value must be one of: `tables`, `tables.fields`."}}
+             ((mt/user->client :lucky) :get 400 (format "database/%d?include=schemas" (mt/id))))))))
 
-;; ## POST /api/database
 (defn- create-db-via-api! [& [m]]
   (let [db-name (mt/random-name)]
     (try
@@ -110,31 +198,31 @@
       (finally (db/delete! Database :name db-name)))))
 
 (deftest create-db-test
-  (testing "Check that we can create a Database"
-    (is (schema= (merge
-                  (m/map-vals s/eq default-db-details)
-                  {:created_at java.time.temporal.Temporal
-                   :engine     (s/eq ::test-driver)
-                   :id         su/IntGreaterThanZero
-                   :details    (s/eq {:db "my_db"})
-                   :updated_at java.time.temporal.Temporal
-                   :name       su/NonBlankString
-                   :features   (s/eq (driver.u/features ::test-driver))})
-                 (create-db-via-api!)))))
-
-(deftest set-is-full-sync
-  (testing "can we set `is_full_sync` to `false` when we create the Database?"
-    (is (= {:is_full_sync false}
-           (select-keys (create-db-via-api! {:is_full_sync false}) [:is_full_sync])))))
-
-(deftest delete-test
+  (testing "POST /api/database"
+    (testing "Check that we can create a Database"
+      (is (schema= (merge
+                    (m/map-vals s/eq default-db-details)
+                    {:created_at java.time.temporal.Temporal
+                     :engine     (s/eq ::test-driver)
+                     :id         su/IntGreaterThanZero
+                     :details    (s/eq {:db "my_db"})
+                     :updated_at java.time.temporal.Temporal
+                     :name       su/NonBlankString
+                     :features   (s/eq (driver.u/features ::test-driver))})
+                   (create-db-via-api!))))
+
+    (testing "can we set `is_full_sync` to `false` when we create the Database?"
+      (is (= {:is_full_sync false}
+             (select-keys (create-db-via-api! {:is_full_sync false}) [:is_full_sync]))))))
+
+(deftest delete-database-test
   (testing "DELETE /api/database/:id"
     (testing "Check that we can delete a Database"
       (mt/with-temp Database [db]
         ((mt/user->client :crowberto) :delete 204 (format "database/%d" (:id db)))
         (is (false? (db/exists? Database :id (u/get-id db))))))))
 
-(deftest can-update-db-fields-test
+(deftest update-database-test
   (testing "PUT /api/database/:id"
     (testing "Check that we can update fields in a Database"
       (mt/with-temp Database [{db-id :id}]
@@ -157,146 +245,73 @@
                       :name         "Cam's Awesome Toucan Database"
                       :is_full_sync false
                       :features     (driver.u/features :h2)}
-                     (into {} (db/select-one [Database :name :engine :details :is_full_sync], :id db-id)))))))))))
-
-(deftest set-auto-run-queries-test
-  (testing "should be able to set `auto_run_queries`"
-    (testing "when creating a Database"
-      (is (= {:auto_run_queries false}
-             (select-keys (create-db-via-api! {:auto_run_queries false}) [:auto_run_queries]))))
-    (testing "when updating a Database"
-      (mt/with-temp Database [{db-id :id} {:engine ::test-driver}]
-        (let [updates {:auto_run_queries false}]
-          ((mt/user->client :crowberto) :put 200 (format "database/%d" db-id) updates))
-        (is (= false
-               (db/select-one-field :auto_run_queries Database, :id db-id)))))))
-
-(def ^:private default-table-details
-  {:description             nil
-   :entity_name             nil
-   :entity_type             "entity/GenericTable"
-   :caveats                 nil
-   :points_of_interest      nil
-   :visibility_type         nil
-   :active                  true
-   :show_in_getting_started false})
-
-(deftest only-superusers-should-see-db-details-test
-  (testing "GET /api/database"
-    (testing "Test that we can get all the DBs (ordered by name, then driver)"
-      (testing "Database details *should not* come back for Rasta since she's not a superuser"
-        (let [expected-keys (-> (into #{:features :native_permissions} (keys (Database (mt/id))))
-                                (disj :details))]
-          (doseq [db ((mt/user->client :rasta) :get 200 "database")]
-            (testing (format "Database %s %d %s" (:engine db) (u/get-id db) (pr-str (:name db)))
-              (is (= expected-keys
-                     (set (keys db)))))))))))
-
-(defn- table-details [table]
-  (-> default-table-details
-      (merge
-       (select-keys table [:active :created_at :db_id :description :display_name :entity_name :entity_type :fields_hash
-                           :id :name :rows :schema :updated_at :visibility_type]))
-      (update :entity_type (fn [entity-type]
-                             (when entity-type
-                               (str "entity/" (name entity-type)))))
-      (update :visibility_type #(when % (name %)))))
-
-(defn- expected-tables [db-or-id]
-  (map table-details (db/select Table
-                       :db_id (u/get-id db-or-id), :active true
-                       {:order-by [[:%lower.schema :asc] [:%lower.display_name :asc]]})))
-
-(deftest db-endpoint-includes-tables-test
-  (testing "GET /api/databases?include_tables=true"
-    (mt/with-temp Database [{db-id :id, db-name :name} {:engine (u/qualified-name ::test-driver)}]
-      (doseq [db ((mt/user->client :rasta) :get 200 "database" :include_tables true)]
-        (testing (format "Database %s %d %s" (:engine db) (u/get-id db) (pr-str (:name db)))
-          (is (= (expected-tables db)
-                 (:tables db))))))))
+                     (into {} (db/select-one [Database :name :engine :details :is_full_sync], :id db-id)))))))))
+
+    (testing "should be able to set `auto_run_queries`"
+      (testing "when creating a Database"
+        (is (= {:auto_run_queries false}
+               (select-keys (create-db-via-api! {:auto_run_queries false}) [:auto_run_queries]))))
+      (testing "when updating a Database"
+        (mt/with-temp Database [{db-id :id} {:engine ::test-driver}]
+          (let [updates {:auto_run_queries false}]
+            ((mt/user->client :crowberto) :put 200 (format "database/%d" db-id) updates))
+          (is (= false
+                 (db/select-one-field :auto_run_queries Database, :id db-id))))))))
 
-;; ## GET /api/database/:id/metadata
-(def ^:private default-field-details
-  {:description        nil
-   :caveats            nil
-   :points_of_interest nil
-   :active             true
-   :position           0
-   :target             nil
-   :preview_display    true
-   :parent_id          nil
-   :settings           nil})
+(deftest fetch-database-metadata-test
+  (testing "GET /api/database/:id/metadata"
+    (is (= (merge default-db-details
+                  (select-keys (mt/db) [:created_at :id :updated_at :timezone])
+                  {:engine   "h2"
+                   :name     "test-data"
+                   :features (map u/qualified-name (driver.u/features :h2))
+                   :tables   [(merge
+                               default-table-details
+                               (db/select-one [Table :created_at :updated_at :fields_hash] :id (mt/id :categories))
+                               {:schema       "PUBLIC"
+                                :name         "CATEGORIES"
+                                :display_name "Categories"
+                                :fields       [(merge
+                                                (field-details (Field (mt/id :categories :id)))
+                                                {:table_id         (mt/id :categories)
+                                                 :special_type     "type/PK"
+                                                 :name             "ID"
+                                                 :display_name     "ID"
+                                                 :database_type    "BIGINT"
+                                                 :base_type        "type/BigInteger"
+                                                 :visibility_type  "normal"
+                                                 :has_field_values "none"})
+                                               (merge
+                                                (field-details (Field (mt/id :categories :name)))
+                                                {:table_id         (mt/id :categories)
+                                                 :special_type     "type/Name"
+                                                 :name             "NAME"
+                                                 :display_name     "Name"
+                                                 :database_type    "VARCHAR"
+                                                 :base_type        "type/Text"
+                                                 :visibility_type  "normal"
+                                                 :has_field_values "list"})]
+                                :segments     []
+                                :metrics      []
+                                :rows         nil
+                                :id           (mt/id :categories)
+                                :db_id        (mt/id)})]})
+           (let [resp ((mt/user->client :rasta) :get 200 (format "database/%d/metadata" (mt/id)))]
+             (assoc resp :tables (filter #(= "CATEGORIES" (:name %)) (:tables resp))))))))
+
+(deftest autocomplete-suggestions-test
+  (testing "GET /api/database/:id/autocomplete_suggestions"
+    (doseq [[prefix expected] {"u"   [["USERS" "Table"]
+                                      ["USER_ID" "CHECKINS :type/Integer :type/FK"]]
+                               "c"   [["CATEGORIES" "Table"]
+                                      ["CHECKINS" "Table"]
+                                      ["CATEGORY_ID" "VENUES :type/Integer :type/FK"]]
+                               "cat" [["CATEGORIES" "Table"]
+                                      ["CATEGORY_ID" "VENUES :type/Integer :type/FK"]]}]
+      (is (= expected
+             ((mt/user->client :rasta) :get 200 (format "database/%d/autocomplete_suggestions" (mt/id)) :prefix prefix))))))
 
-(defn- field-details [field]
-  (merge
-   default-field-details
-   (select-keys
-    field
-    [:updated_at :id :created_at :last_analyzed :fingerprint :fingerprint_version :fk_target_field_id])))
 
-(deftest fetch-database-metadata-test
-  (is (= (merge default-db-details
-                (select-keys (mt/db) [:created_at :id :updated_at :timezone])
-                {:engine   "h2"
-                 :name     "test-data"
-                 :features (map u/qualified-name (driver.u/features :h2))
-                 :tables   [(merge
-                             default-table-details
-                             (db/select-one [Table :created_at :updated_at :fields_hash] :id (mt/id :categories))
-                             {:schema       "PUBLIC"
-                              :name         "CATEGORIES"
-                              :display_name "Categories"
-                              :fields       [(merge
-                                              (field-details (Field (mt/id :categories :id)))
-                                              {:table_id         (mt/id :categories)
-                                               :special_type     "type/PK"
-                                               :name             "ID"
-                                               :display_name     "ID"
-                                               :database_type    "BIGINT"
-                                               :base_type        "type/BigInteger"
-                                               :visibility_type  "normal"
-                                               :has_field_values "none"})
-                                             (merge
-                                              (field-details (Field (mt/id :categories :name)))
-                                              {:table_id         (mt/id :categories)
-                                               :special_type     "type/Name"
-                                               :name             "NAME"
-                                               :display_name     "Name"
-                                               :database_type    "VARCHAR"
-                                               :base_type        "type/Text"
-                                               :visibility_type  "normal"
-                                               :has_field_values "list"})]
-                              :segments     []
-                              :metrics      []
-                              :rows         nil
-                              :id           (mt/id :categories)
-                              :db_id        (mt/id)})]})
-         (let [resp ((mt/user->client :rasta) :get 200 (format "database/%d/metadata" (mt/id)))]
-           (assoc resp :tables (filter #(= "CATEGORIES" (:name %)) (:tables resp)))))))
-
-
-;;; GET /api/database/:id/autocomplete_suggestions
-
-(defn- suggestions-with-prefix [prefix]
-  ((mt/user->client :rasta) :get 200 (format "database/%d/autocomplete_suggestions" (mt/id)) :prefix prefix))
-
-(deftest succestions-with-prefix
-  (is (= [["USERS" "Table"]
-          ["USER_ID" "CHECKINS :type/Integer :type/FK"]]
-         (suggestions-with-prefix "u")))
-
-  (is (= [["CATEGORIES" "Table"]
-          ["CHECKINS" "Table"]
-          ["CATEGORY_ID" "VENUES :type/Integer :type/FK"]]
-         (suggestions-with-prefix "c")))
-
-  (is (= [["CATEGORIES" "Table"]
-          ["CATEGORY_ID" "VENUES :type/Integer :type/FK"]]
-         (suggestions-with-prefix "cat"))))
-
-
-;;; GET /api/database?include_cards=true
-;; Check that we get back 'virtual' tables for Saved Questions
 (defn- card-with-native-query {:style/indent 1} [card-name & {:as kvs}]
   (merge
    {:name          card-name
@@ -329,126 +344,119 @@
     :description  nil}
    kvs))
 
-(deftest saved-questions-db-is-last-on-list
-  (mt/with-temp* [Card [card (card-with-native-query "Kanye West Quote Views Per Month")]]
-    ;; run the Card which will populate its result_metadata column
-    ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card)))
-    ;; Now fetch the database list. The 'Saved Questions' DB should be last on the list
-    (is (= (-> card
-               virtual-table-for-card
-               saved-questions-virtual-db)
-           (last ((mt/user->client :crowberto) :get 200 "database" :include_cards true))))))
-
-(deftest saved-questions-not-inluded-if-setting-disabled
-  (testing "Make sure saved questions are NOT included if the setting is disabled"
-    (mt/with-temp Card [card (card-with-native-query "Kanye West Quote Views Per Month")]
-      (mt/with-temporary-setting-values [enable-nested-queries false]
-        ;; run the Card which will populate its result_metadata column
-        ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card)))
-        ;; Now fetch the database list. The 'Saved Questions' DB should NOT be in the list
-        (is (= nil
-               (some (fn [database]
-                       (when (= (u/get-id database) mbql.s/saved-questions-virtual-database-id)
-                         database))
-                     ((mt/user->client :crowberto) :get 200 "database" :include_cards true))))))))
-
-(deftest pretend-collections-are-schemas
-  (testing "make sure that GET /api/database?include_cards=true groups pretends COLLECTIONS are SCHEMAS"
-    (mt/with-temp* [Collection [stamp-collection {:name "Stamps"}]
-                    Collection [coin-collection  {:name "Coins"}]
-                    Card       [stamp-card (card-with-native-query "Total Stamp Count", :collection_id (u/get-id stamp-collection))]
-                    Card       [coin-card  (card-with-native-query "Total Coin Count",  :collection_id (u/get-id coin-collection))]]
-      ;; run the Cards which will populate their result_metadata columns
-      (doseq [card [stamp-card coin-card]]
-        ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card))))
-      ;; Now fetch the database list. The 'Saved Questions' DB should be last on the list. Cards should have their
-      ;; Collection name as their Schema
-      (is (= (saved-questions-virtual-db
-               (virtual-table-for-card coin-card  :schema "Coins")
-               (virtual-table-for-card stamp-card :schema "Stamps"))
-             (last ((mt/user->client :crowberto) :get 200 "database" :include_cards true)))))))
-
 (defn- fetch-virtual-database []
   (some #(when (= (:name %) "Saved Questions")
            %)
         ((mt/user->client :crowberto) :get 200 "database" :include_cards true)))
 
-(deftest remove-cards-with-ambiguous-columns
-  (testing "make sure that GET /api/database?include_cards=true removes Cards that have ambiguous columns"
-    (mt/with-temp* [Card [ok-card         (assoc (card-with-native-query "OK Card")         :result_metadata [{:name "cam"}])]
-                    Card [cambiguous-card (assoc (card-with-native-query "Cambiguous Card") :result_metadata [{:name "cam"} {:name "cam_2"}])]]
-      (is (= (-> ok-card
-                 virtual-table-for-card
-                 saved-questions-virtual-db)
-             (fetch-virtual-database))))))
-
-;; make sure that GET /api/database/include_cards=true removes Cards that belong to a driver that doesn't support
-;; nested queries
 (driver/register! ::no-nested-query-support
                   :parent :sql-jdbc
                   :abstract? true)
 
 (defmethod driver/supports? [::no-nested-query-support :nested-queries] [_ _] false)
 
-(deftest fetch-saved-questions-db-test
-  (mt/with-temp* [Database [bad-db   {:engine ::no-nested-query-support, :details {}}]
-                  Card     [bad-card {:name            "Bad Card"
-                                      :dataset_query   {:database (u/get-id bad-db)
-                                                        :type     :native
-                                                        :native   {:query "[QUERY GOES HERE]"}}
-                                      :result_metadata [{:name "sparrows"}]
-                                      :database_id     (u/get-id bad-db)}]
-                  Card     [ok-card  (assoc (card-with-native-query "OK Card")
-                                            :result_metadata [{:name "finches"}])]]
-    (is (= (-> ok-card
-               virtual-table-for-card
-               saved-questions-virtual-db)
-           (fetch-virtual-database)))))
-
-
-;; make sure that GET /api/database?include_cards=true removes Cards that use cumulative-sum and cumulative-count
-;; aggregations
 (defn- ok-mbql-card []
   (assoc (card-with-mbql-query "OK Card"
                                :source-table (mt/id :checkins))
          :result_metadata [{:name "num_toucans"}]))
 
-;; cumulative count
-(deftest cumulative-count
-  (mt/with-temp* [Card [ok-card (ok-mbql-card)]
-                  Card [_ (merge
-                           (mt/$ids checkins
-                                      (card-with-mbql-query "Cum Count Card"
-                                                            :source-table $$checkins
-                                                            :aggregation  [[:cum-count]]
-                                                            :breakout     [!month.date]))
-                           {:result_metadata [{:name "num_toucans"}]})]]
-    (is (= (-> ok-card
-               virtual-table-for-card
-               saved-questions-virtual-db)
-           (fetch-virtual-database)))))
-
-;; make sure that GET /api/database/:id/metadata works for the Saved Questions 'virtual' database
-(deftest works-with-saved-questions-virtual-db
-  (mt/with-temp* [Card [card (assoc (card-with-native-query "Birthday Card")
-                                    :result_metadata [{:name "age_in_bird_years"}])]]
-    (is (= (saved-questions-virtual-db
-            (assoc (virtual-table-for-card card)
-                   :fields [{:name                     "age_in_bird_years"
-                             :table_id                 (str "card__" (u/get-id card))
-                             :id                       ["field-literal" "age_in_bird_years" "type/*"]
-                             :special_type             nil
-                             :base_type                nil
-                             :default_dimension_option nil
-                             :dimension_options        []}]))
-           ((mt/user->client :crowberto) :get 200
-            (format "database/%d/metadata" mbql.s/saved-questions-virtual-database-id))))))
-
-(deftest return-nil-when-no-eligible-saved-questions
-  (testing "if no eligible Saved Questions exist the virtual DB metadata endpoint should just return `nil`"
-    (is (= nil
-           ((mt/user->client :crowberto) :get 204
-            (format "database/%d/metadata" mbql.s/saved-questions-virtual-database-id))))))
+(deftest databases-list-include-saved-questions-test
+  (testing "GET /api/database?include_cards=true"
+    (testing "Check that we get back 'virtual' tables for Saved Questions"
+      (testing "The saved questions virtual DB should be the last DB in the list"
+        (mt/with-temp* [Card [card (card-with-native-query "Kanye West Quote Views Per Month")]]
+          ;; run the Card which will populate its result_metadata column
+          ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card)))
+          ;; Now fetch the database list. The 'Saved Questions' DB should be last on the list
+          (is (= (-> card
+                     virtual-table-for-card
+                     saved-questions-virtual-db)
+                 (last ((mt/user->client :crowberto) :get 200 "database" :include_cards true))))))
+
+      (testing "Make sure saved questions are NOT included if the setting is disabled"
+        (mt/with-temp Card [card (card-with-native-query "Kanye West Quote Views Per Month")]
+          (mt/with-temporary-setting-values [enable-nested-queries false]
+            ;; run the Card which will populate its result_metadata column
+            ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card)))
+            ;; Now fetch the database list. The 'Saved Questions' DB should NOT be in the list
+            (is (= nil
+                   (some (fn [database]
+                           (when (= (u/get-id database) mbql.s/saved-questions-virtual-database-id)
+                             database))
+                         ((mt/user->client :crowberto) :get 200 "database" :include_cards true))))))))
+
+    (testing "should pretend Collections are schemas"
+      (mt/with-temp* [Collection [stamp-collection {:name "Stamps"}]
+                      Collection [coin-collection  {:name "Coins"}]
+                      Card       [stamp-card (card-with-native-query "Total Stamp Count", :collection_id (u/get-id stamp-collection))]
+                      Card       [coin-card  (card-with-native-query "Total Coin Count",  :collection_id (u/get-id coin-collection))]]
+        ;; run the Cards which will populate their result_metadata columns
+        (doseq [card [stamp-card coin-card]]
+          ((mt/user->client :crowberto) :post 202 (format "card/%d/query" (u/get-id card))))
+        ;; Now fetch the database list. The 'Saved Questions' DB should be last on the list. Cards should have their
+        ;; Collection name as their Schema
+        (is (= (saved-questions-virtual-db
+                 (virtual-table-for-card coin-card  :schema "Coins")
+                 (virtual-table-for-card stamp-card :schema "Stamps"))
+               (last ((mt/user->client :crowberto) :get 200 "database" :include_cards true))))))
+
+    (testing "should remove Cards that have ambiguous columns"
+      (mt/with-temp* [Card [ok-card         (assoc (card-with-native-query "OK Card")         :result_metadata [{:name "cam"}])]
+                      Card [cambiguous-card (assoc (card-with-native-query "Cambiguous Card") :result_metadata [{:name "cam"} {:name "cam_2"}])]]
+        (is (= (-> ok-card
+                   virtual-table-for-card
+                   saved-questions-virtual-db)
+               (fetch-virtual-database)))))
+
+    (testing "should remove Cards that belong to a driver that doesn't support nested queries"
+      (mt/with-temp* [Database [bad-db   {:engine ::no-nested-query-support, :details {}}]
+                      Card     [bad-card {:name            "Bad Card"
+                                          :dataset_query   {:database (u/get-id bad-db)
+                                                            :type     :native
+                                                            :native   {:query "[QUERY GOES HERE]"}}
+                                          :result_metadata [{:name "sparrows"}]
+                                          :database_id     (u/get-id bad-db)}]
+                      Card     [ok-card  (assoc (card-with-native-query "OK Card")
+                                                :result_metadata [{:name "finches"}])]]
+        (is (= (-> ok-card
+                   virtual-table-for-card
+                   saved-questions-virtual-db)
+               (fetch-virtual-database)))))
+
+    (testing "should remove Cards that use cumulative-sum and cumulative-count aggregations"
+      (mt/with-temp* [Card [ok-card (ok-mbql-card)]
+                      Card [_ (merge
+                               (mt/$ids checkins
+                                 (card-with-mbql-query "Cum Count Card"
+                                   :source-table $$checkins
+                                   :aggregation  [[:cum-count]]
+                                   :breakout     [!month.date]))
+                               {:result_metadata [{:name "num_toucans"}]})]]
+        (is (= (-> ok-card
+                   virtual-table-for-card
+                   saved-questions-virtual-db)
+               (fetch-virtual-database)))))))
+
+(deftest db-metadata-saved-questions-db-test
+  (testing "GET /api/database/:id/metadata works for the Saved Questions 'virtual' database"
+    (mt/with-temp* [Card [card (assoc (card-with-native-query "Birthday Card")
+                                      :result_metadata [{:name "age_in_bird_years"}])]]
+      (is (= (saved-questions-virtual-db
+               (assoc (virtual-table-for-card card)
+                      :fields [{:name                     "age_in_bird_years"
+                                :table_id                 (str "card__" (u/get-id card))
+                                :id                       ["field-literal" "age_in_bird_years" "type/*"]
+                                :special_type             nil
+                                :base_type                nil
+                                :default_dimension_option nil
+                                :dimension_options        []}]))
+             ((mt/user->client :crowberto) :get 200
+              (format "database/%d/metadata" mbql.s/saved-questions-virtual-database-id)))))
+
+    (testing "if no eligible Saved Questions exist the virtual DB metadata endpoint should just return `nil`"
+      (is (= nil
+             ((mt/user->client :crowberto) :get 204
+              (format "database/%d/metadata" mbql.s/saved-questions-virtual-database-id)))))))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -571,8 +579,6 @@
          ((mt/user->client :rasta) :post 403 (format "database/%d/discard_values" (mt/id))))))
 
 
-;;; Tests for /POST /api/database/validate
-
 ;; For some stupid reason the *real* version of `test-database-connection` is set up to do nothing for tests. I'm
 ;; guessing it's done that way so we can save invalid DBs for some silly tests. Instead of doing it the right way
 ;; and using `with-redefs` to disable it in the few tests where it makes sense, we actually have to use `with-redefs`
@@ -582,34 +588,33 @@
     nil
     {:valid false, :message "Error!"}))
 
-(deftest nonadmins-cant-do-something
-  (is (= "You don't have permissions to do that."
-         (with-redefs [database-api/test-database-connection test-database-connection]
-           ((mt/user->client :rasta) :post 403 "database/validate"
-            {:details {:engine :h2, :details (:details (mt/db))}})))))
-
-(deftest gets-details
-  (is (= (:details (mt/db))
-         (with-redefs [database-api/test-database-connection test-database-connection]
-           (#'database-api/test-connection-details "h2" (:details (mt/db)))))))
-
-(deftest validate-database-details-test
-  (with-redefs [database-api/test-database-connection test-database-connection]
-    (testing "Valid database connection details"
-      (is (= {:valid true}
-             ((mt/user->client :crowberto) :post 200 "database/validate"
-              {:details {:engine :h2, :details (:details (mt/db))}}))))
-
-    (testing "invalid database connection details"
-      (mt/suppress-output
-        (testing "calling test-connection-details directly"
-          (is (= {:valid false, :message "Error!"}
-                 (#'database-api/test-connection-details "h2" {:db "ABC"}))))
-
-        (testing "via the API endpoint"
-          (is (= {:valid false}
-                 ((mt/user->client :crowberto) :post 200 "database/validate"
-                  {:details {:engine :h2, :details {:db "ABC"}}}))))))))
+(deftest validate-database-test
+  (testing "POST /api/database/validate"
+    (with-redefs [database-api/test-database-connection test-database-connection]
+      (testing "Should require superuser permissions"
+        (is (= "You don't have permissions to do that."
+               ((mt/user->client :rasta) :post 403 "database/validate"
+                {:details {:engine :h2, :details (:details (mt/db))}}))))
+
+      (testing "Underlying `test-connection-details` function should work"
+        (is (= (:details (mt/db))
+               (#'database-api/test-connection-details "h2" (:details (mt/db))))))
+
+      (testing "Valid database connection details"
+        (is (= {:valid true}
+               ((mt/user->client :crowberto) :post 200 "database/validate"
+                {:details {:engine :h2, :details (:details (mt/db))}}))))
+
+      (testing "invalid database connection details"
+        (mt/suppress-output
+          (testing "calling test-connection-details directly"
+            (is (= {:valid false, :message "Error!"}
+                   (#'database-api/test-connection-details "h2" {:db "ABC"}))))
+
+          (testing "via the API endpoint"
+            (is (= {:valid false}
+                   ((mt/user->client :crowberto) :post 200 "database/validate"
+                    {:details {:engine :h2, :details {:db "ABC"}}})))))))))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+