Repository: dbt-labs/dbt-core

Issue:
Use `show objects in schema` on Snowflake
### Describe the feature
dbt should leverage the `show terse objects in schema` query to list the tables and views in a database. Crucially, `show ....` queries _do not require a running warehouse_, so they will not queue in the virtual warehouse (leading to long perceived startup times).

Caveats:
 - Snowflake's docs indicate that only 10k records can be returned from one of these queries. I'd like to talk to someone from Snowflake to get an understanding if this limit is still accurate, or if they have near-term plans to lift this restriction.
 - The existing info schema query gets away with a case-insensitive lookup using `ilike, but we'll need to quote and case the schema name exactly for this query to succeed.
- Per [the docs](https://docs.snowflake.net/manuals/sql-reference/sql/show-objects.html), materialized views are returned with type `VIEW`, which is kind of unpleasant.
- We should post-process the results in Python instead of using `result_scan`, because selecting from `result_scan` can queue


Discussion:

Resolving patch:
diff --git a/plugins/snowflake/dbt/adapters/snowflake/impl.py b/plugins/snowflake/dbt/adapters/snowflake/impl.py
--- a/plugins/snowflake/dbt/adapters/snowflake/impl.py
+++ b/plugins/snowflake/dbt/adapters/snowflake/impl.py
@@ -3,7 +3,10 @@
 import agate
 
 from dbt.adapters.sql import SQLAdapter
-from dbt.adapters.sql.impl import LIST_SCHEMAS_MACRO_NAME
+from dbt.adapters.sql.impl import (
+    LIST_SCHEMAS_MACRO_NAME,
+    LIST_RELATIONS_MACRO_NAME,
+)
 from dbt.adapters.snowflake import SnowflakeConnectionManager
 from dbt.adapters.snowflake import SnowflakeRelation
 from dbt.adapters.snowflake import SnowflakeColumn
@@ -99,3 +102,43 @@ def list_schemas(self, database: str) -> List[str]:
         # want is 'name'
 
         return [row['name'] for row in results]
+
+    def list_relations_without_caching(
+            self, information_schema, schema
+    ) -> List[SnowflakeRelation]:
+        kwargs = {'information_schema': information_schema, 'schema': schema}
+        try:
+            results = self.execute_macro(
+                LIST_RELATIONS_MACRO_NAME,
+                kwargs=kwargs
+            )
+        except DatabaseException as exc:
+            # if the schema doesn't exist, we just want to return.
+            # Alternatively, we could query the list of schemas before we start
+            # and skip listing the missing ones, which sounds expensive.
+            if 'Object does not exist' in str(exc):
+                return []
+            raise
+
+        relations = []
+        quote_policy = {
+            'database': True,
+            'schema': True,
+            'identifier': True
+        }
+
+        columns = ['database_name', 'schema_name', 'name', 'kind']
+        for _database, _schema, _identifier, _type in results.select(columns):
+            try:
+                _type = self.Relation.get_relation_type(_type.lower())
+            except ValueError:
+                _type = self.Relation.External
+            relations.append(self.Relation.create(
+                database=_database,
+                schema=_schema,
+                identifier=_identifier,
+                quote_policy=quote_policy,
+                type=_type
+            ))
+
+        return relations


Test patch: