Repository: dbt-labs/dbt-core

Issue:
Curious sortkey override behavior
### Describe the bug
We’ve run into an issue with defining sort config parameters in multiple places if both values are lists.

If…
1. a default sort config is defined in the dbt_project;
2. a model-specific sort parameter is defined; and
3. both sort configurations are lists

then the resulting sort key is a concatenation of all of the keys, at least on Redshift (not sure how platform-dependent this might be).

### Steps To Reproduce
Define a list of sort keys on a particular path in dbt_project
```yaml
models:
  project_name:
    events:
      sort: ['occurred_at', 'client']
```

Then, create a new model in that path (e.g., `project_name/events/cool_events_facts.sql`) and redefine sort-keys
```
{{
    config(
        sort=['day_of_week','version']
    )
}}
```

When the model is built, the resulting SQL concatenates all four values, something like this (on Redshift):
```SQL
create table
    events.cool_events_facts
    compound sortkey(day_of_week,version,occurred_at,client)
as (
    select *
    from whatever
);
```

### Expected behavior
My expectation is that the model-specific sort param overrides those in dbt_project, which is what happens when a string literal is used instead of a list. 

### Screenshots and log output
LMK if you need any more info!

### System information
**Which database are you using dbt with?**
- [ ] postgres
- [x] redshift
- [ ] bigquery
- [ ] snowflake
- [ ] other (specify: ____________)


**The output of `dbt --version`:**
```
installed version: 0.15.0
   latest version: 0.15.0

Up to date!
```

**The operating system you're using:**

macOS v10.14.6

**The output of `python --version`:**

Python 3.7.6

### Additional context
Our current workaround is to define the model-specific sort params in dbt_project, which seems to override as expected.



Discussion:

Resolving patch:
diff --git a/core/dbt/source_config.py b/core/dbt/source_config.py
--- a/core/dbt/source_config.py
+++ b/core/dbt/source_config.py
@@ -50,9 +50,16 @@ def __init__(self, active_project, own_project, fqn, node_type):
     def _merge(self, *configs):
         merged_config = {}
         for config in configs:
+            # Do not attempt to deep merge clobber fields
+            config = config.copy()
+            clobber = {
+                key: config.pop(key) for key in list(config.keys())
+                if key in (self.ClobberFields | self.AdapterSpecificConfigs)
+            }
             intermediary_merged = deep_merge(
-                merged_config.copy(), config.copy()
+                merged_config, config
             )
+            intermediary_merged.update(clobber)
 
             merged_config.update(intermediary_merged)
         return merged_config


Test patch:
diff --git a/test/unit/test_source_config.py b/test/unit/test_source_config.py
--- a/test/unit/test_source_config.py
+++ b/test/unit/test_source_config.py
@@ -120,6 +120,28 @@ def test__source_config_multiple_calls(self):
         }
         self.assertEqual(cfg.config, expect)
 
+    def test__source_config_merge(self):
+        self.root_project_config.models = {'sort': ['a', 'b']}
+        cfg = SourceConfig(self.root_project_config, self.root_project_config,
+                           ['root', 'x'], NodeType.Model)
+        cfg.update_in_model_config({
+            'materialized': 'something',
+            'sort': ['d', 'e']
+        })
+        expect = {
+            'column_types': {},
+            'enabled': True,
+            'materialized': 'something',
+            'post-hook': [],
+            'pre-hook': [],
+            'persist_docs': {},
+            'quoting': {},
+            'sort': ['d', 'e'],
+            'tags': [],
+            'vars': {},
+        }
+        self.assertEqual(cfg.config, expect)
+
     def test_source_config_all_keys_accounted_for(self):
         used_keys = frozenset(SourceConfig.AppendListFields) | \
                     frozenset(SourceConfig.ExtendDictFields) | \