forked from dbt-labs/dbt-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunion.sql
More file actions
134 lines (94 loc) · 4.67 KB
/
union.sql
File metadata and controls
134 lines (94 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{%- macro union_relations(relations, column_override=none, include=[], exclude=[], source_column_name='_dbt_source_relation', where=none) -%}
{{ return(adapter.dispatch('union_relations', 'dbt_utils')(relations, column_override, include, exclude, source_column_name, where)) }}
{% endmacro %}
{%- macro default__union_relations(relations, column_override=none, include=[], exclude=[], source_column_name='_dbt_source_relation', where=none) -%}
{%- if exclude and include -%}
{{ exceptions.raise_compiler_error("Both an exclude and include list were provided to the `union` macro. Only one is allowed") }}
{%- endif -%}
{#-- Prevent querying of db in parsing mode. This works because this macro does not create any new refs. -#}
{%- if not execute %}
{{ return('') }}
{% endif -%}
{%- set column_override = column_override if column_override is not none else {} -%}
{%- set relation_columns = {} -%}
{%- set column_superset = {} -%}
{%- set all_excludes = [] -%}
{%- set all_includes = [] -%}
{%- if exclude -%}
{%- for exc in exclude -%}
{%- do all_excludes.append(exc | lower) -%}
{%- endfor -%}
{%- endif -%}
{%- if include -%}
{%- for inc in include -%}
{%- do all_includes.append(inc | lower) -%}
{%- endfor -%}
{%- endif -%}
{%- for relation in relations -%}
{%- do relation_columns.update({relation: []}) -%}
{%- do dbt_utils._is_relation(relation, 'union_relations') -%}
{%- do dbt_utils._is_ephemeral(relation, 'union_relations') -%}
{%- set cols = adapter.get_columns_in_relation(relation) -%}
{%- for col in cols -%}
{#- If an exclude list was provided and the column is in the list, do nothing -#}
{%- if exclude and col.column | lower in all_excludes -%}
{#- If an include list was provided and the column is not in the list, do nothing -#}
{%- elif include and col.column | lower not in all_includes -%}
{#- Otherwise add the column to the column superset -#}
{%- else -%}
{#- update the list of columns in this relation -#}
{%- do relation_columns[relation].append(col.column) -%}
{%- if col.column in column_superset -%}
{%- set stored = column_superset[col.column] -%}
{%- if col.is_string() and stored.is_string() and col.string_size() > stored.string_size() -%}
{%- do column_superset.update({col.column: col}) -%}
{%- endif %}
{%- else -%}
{%- do column_superset.update({col.column: col}) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- set ordered_column_names = column_superset.keys() -%}
{%- set dbt_command = flags.WHICH -%}
{% if dbt_command in ['run', 'build'] %}
{% if (include | length > 0 or exclude | length > 0) and not column_superset.keys() %}
{%- set relations_string -%}
{%- for relation in relations -%}
{{ relation.name }}
{%- if not loop.last %}, {% endif -%}
{%- endfor -%}
{%- endset -%}
{%- set error_message -%}
There were no columns found to union for relations {{ relations_string }}
{%- endset -%}
{{ exceptions.raise_compiler_error(error_message) }}
{%- endif -%}
{%- endif -%}
{%- for relation in relations %}
(
select
{%- if source_column_name is not none %}
cast({{ dbt.string_literal(relation.render()) }} as {{ dbt.type_string() }}) as {{ source_column_name }},
{%- endif %}
/* No columns from any of the relations.
This star is only output during dbt compile, and exists to keep SQLFluff happy. */
{% if dbt_command == 'compile' and ordered_column_names|length == 0 %}
*
{% endif %}
{% for col_name in ordered_column_names -%}
{%- set col = column_superset[col_name] %}
{%- set col_type = column_override.get(col.column, col.data_type) %}
{%- set col_name = adapter.quote(col_name) if col_name in relation_columns[relation] else 'null' %}
cast({{ col_name }} as {{ col_type }}) as {{ col.quoted }} {% if not loop.last %},{% endif -%}
{%- endfor %}
from {{ relation }}
{% if where -%}
where {{ where }}
{%- endif %}
)
{% if not loop.last -%}
union all
{% endif -%}
{%- endfor -%}
{%- endmacro -%}