Repository: dbt-labs/dbt-core

Issue:
dbt Server errors when returning Array types in Postgres
### Describe the bug

There's some sort of agate-internal issue with converting array type columns to an Agate dataframe from a Postgres response. TBD what the exact culprit is, but it manifests as `tuple.index(x): x not in tuple` called via `agate_table.table_from_data` (specifically in `table.select(column_names)`). There's a solid reproduction case attached below.

### Steps To Reproduce
Run the query:
```
select ARRAY[10000, 10000, 10000, 10000]
```

against a running rpc server. Poll for a response and see the error:
```
Traceback (most recent call last):
  File \"/Users/drew/fishtown/dbt/core/dbt/node_runners.py\", line 227, in safe_run
    result = self.compile_and_execute(manifest, ctx)
  File \"/Users/drew/fishtown/dbt/core/dbt/node_runners.py\", line 170, in compile_and_execute
    result = self.run(ctx.node, manifest)
  File \"/Users/drew/fishtown/dbt/core/dbt/node_runners.py\", line 272, in run
    return self.execute(compiled_node, manifest)
  File \"/Users/drew/fishtown/dbt/core/dbt/rpc/node_runners.py\", line 86, in execute
    compiled_node.injected_sql, fetch=True
  File \"/Users/drew/fishtown/dbt/core/dbt/adapters/base/impl.py\", line 227, in execute
    fetch=fetch
  File \"/Users/drew/fishtown/dbt/core/dbt/adapters/sql/connections.py\", line 119, in execute
    table = self.get_result_from_cursor(cursor)
  File \"/Users/drew/fishtown/dbt/core/dbt/adapters/sql/connections.py\", line 110, in get_result_from_cursor
    return dbt.clients.agate_helper.table_from_data(data, column_names)
  File \"/Users/drew/fishtown/dbt/core/dbt/clients/agate_helper.py\", line 84, in table_from_data
    return table.select(column_names)
  File \"/Users/drew/fishtown/dbt/env/lib/python3.7/site-packages/agate/table/select.py\", line 21, in select
    indexes = tuple(self._column_names.index(k) for k in key)
  File \"/Users/drew/fishtown/dbt/env/lib/python3.7/site-packages/agate/table/select.py\", line 21, in <genexpr>
    indexes = tuple(self._column_names.index(k) for k in key)
ValueError: tuple.index(x): x not in tuple
```

### Expected behavior
I'd expect this query to return data successfully. The Array field should be json-ified, as with non-primitive types on other datbases (BQ, Snowflake).

### System information
**Which database are you using dbt with?**
- [x] postgres

**The output of `dbt --version`:**
```
0.16.0
```


Discussion:
Update:

```
select ARRAY[10000, 10000, 10000, 10000]
```

```
ipdb> table.print_table()
| array/0 | array/1 | array/2 | array/3 |
| ------- | ------- | ------- | ------- |
|  10,000 |  10,000 |  10,000 |  10,000 |
```

Thanks, Agate! 

Resolving patch:
diff --git a/core/dbt/adapters/sql/connections.py b/core/dbt/adapters/sql/connections.py
--- a/core/dbt/adapters/sql/connections.py
+++ b/core/dbt/adapters/sql/connections.py
@@ -107,7 +107,10 @@ def get_result_from_cursor(cls, cursor: Any) -> agate.Table:
             rows = cursor.fetchall()
             data = cls.process_results(column_names, rows)
 
-        return dbt.clients.agate_helper.table_from_data(data, column_names)
+        return dbt.clients.agate_helper.table_from_data_flat(
+            data,
+            column_names
+        )
 
     def execute(
         self, sql: str, auto_begin: bool = False, fetch: bool = False


Test patch:
diff --git a/test/integration/060_run_query_tests/macros/test_pg_array_queries.sql b/test/integration/060_run_query_tests/macros/test_pg_array_queries.sql
new file mode 100644
--- /dev/null
+++ b/test/integration/060_run_query_tests/macros/test_pg_array_queries.sql
@@ -0,0 +1,16 @@
+
+{% macro test_array_results() %}
+
+    {% set sql %}
+        select ARRAY[1, 2, 3, 4] as mydata
+    {% endset %}
+
+    {% set result = run_query(sql) %}
+    {% set value = result.columns['mydata'][0] %}
+
+    {# This will be json-stringified #}
+    {% if value != "[1, 2, 3, 4]" %}
+        {% do exceptions.raise_compiler_error("Value was " ~ value) %}
+    {% endif %}
+
+{% endmacro %}
diff --git a/test/integration/060_run_query_tests/test_pg_types.py b/test/integration/060_run_query_tests/test_pg_types.py
new file mode 100644
--- /dev/null
+++ b/test/integration/060_run_query_tests/test_pg_types.py
@@ -0,0 +1,25 @@
+
+from test.integration.base import DBTIntegrationTest, use_profile
+import json
+
+class TestPostgresTypes(DBTIntegrationTest):
+
+    @property
+    def schema(self):
+        return "pg_query_types_060"
+
+    @property
+    def models(self):
+        return "models"
+
+    @property
+    def project_config(self):
+        return {
+            'config-version': 2,
+            'macro-paths': ['macros'],
+        }
+
+    @use_profile('postgres')
+    def test__postgres_nested_types(self):
+        result = self.run_dbt(['run-operation', 'test_array_results'])
+        self.assertTrue(result.success)