-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathadapters.sql
329 lines (273 loc) · 9.43 KB
/
adapters.sql
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
{% macro dist(dist) %}
{%- if dist is not none -%}
{%- set dist = dist.strip().lower() -%}
{%- if dist in ['all', 'even'] -%}
diststyle {{ dist }}
{%- elif dist == "auto" -%}
{%- else -%}
diststyle key distkey ({{ dist }})
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
{% macro sort(sort_type, sort) %}
{%- if sort is not none %}
{{ sort_type | default('compound', boolean=true) }} sortkey(
{%- if sort is string -%}
{%- set sort = [sort] -%}
{%- endif -%}
{%- for item in sort -%}
{{ item }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
)
{%- endif %}
{%- endmacro -%}
{% macro redshift__create_table_as(temporary, relation, sql) -%}
{%- set _dist = config.get('dist') -%}
{%- set _sort_type = config.get(
'sort_type',
validator=validation.any['compound', 'interleaved']) -%}
{%- set _sort = config.get(
'sort',
validator=validation.any[list, basestring]) -%}
{%- set sql_header = config.get('sql_header', none) -%}
{%- set backup = config.get('backup') -%}
{{ sql_header if sql_header is not none }}
{%- set contract_config = config.get('contract') -%}
{%- if contract_config.enforced -%}
create {% if temporary -%}temporary{%- endif %} table
{{ relation.include(database=(not temporary), schema=(not temporary)) }}
{{ get_table_columns_and_constraints() }}
{{ get_assert_columns_equivalent(sql) }}
{%- set sql = get_select_subquery(sql) %}
{% if backup == false -%}backup no{%- endif %}
{{ dist(_dist) }}
{{ sort(_sort_type, _sort) }}
;
insert into {{ relation.include(database=(not temporary), schema=(not temporary)) }}
(
{{ sql }}
)
;
{%- else %}
create {% if temporary -%}temporary{%- endif %} table
{{ relation.include(database=(not temporary), schema=(not temporary)) }}
{% if backup == false -%}backup no{%- endif %}
{{ dist(_dist) }}
{{ sort(_sort_type, _sort) }}
as (
{{ sql }}
);
{%- endif %}
{%- endmacro %}
{% macro redshift__create_view_as(relation, sql) -%}
{%- set binding = config.get('bind', default=True) -%}
{% set bind_qualifier = '' if binding else 'with no schema binding' %}
{%- set sql_header = config.get('sql_header', none) -%}
{{ sql_header if sql_header is not none }}
create view {{ relation }}
{%- set contract_config = config.get('contract') -%}
{%- if contract_config.enforced -%}
{{ get_assert_columns_equivalent(sql) }}
{%- endif %} as (
{{ sql }}
) {{ bind_qualifier }};
{% endmacro %}
{% macro redshift__create_schema(relation) -%}
{{ postgres__create_schema(relation) }}
{% endmacro %}
{% macro redshift__drop_schema(relation) -%}
{{ postgres__drop_schema(relation) }}
{% endmacro %}
{% macro redshift__get_columns_in_relation(relation) -%}
{% call statement('get_columns_in_relation', fetch_result=True) %}
with bound_views as (
select
ordinal_position,
table_schema,
column_name,
data_type,
character_maximum_length,
numeric_precision,
numeric_scale
from information_schema."columns"
where table_name = '{{ relation.identifier }}'
),
unbound_views as (
select
ordinal_position,
view_schema,
col_name,
case
when col_type ilike 'character varying%' then
'character varying'
when col_type ilike 'numeric%' then 'numeric'
else col_type
end as col_type,
case
when col_type like 'character%'
then nullif(REGEXP_SUBSTR(col_type, '[0-9]+'), '')::int
else null
end as character_maximum_length,
case
when col_type like 'numeric%'
then nullif(
SPLIT_PART(REGEXP_SUBSTR(col_type, '[0-9,]+'), ',', 1),
'')::int
else null
end as numeric_precision,
case
when col_type like 'numeric%'
then nullif(
SPLIT_PART(REGEXP_SUBSTR(col_type, '[0-9,]+'), ',', 2),
'')::int
else null
end as numeric_scale
from pg_get_late_binding_view_cols()
cols(view_schema name, view_name name, col_name name,
col_type varchar, ordinal_position int)
where view_name = '{{ relation.identifier }}'
),
external_views as (
select
columnnum,
schemaname,
columnname,
case
when external_type ilike 'character varying%' or external_type ilike 'varchar%'
then 'character varying'
when external_type ilike 'numeric%' then 'numeric'
else external_type
end as external_type,
case
when external_type like 'character%' or external_type like 'varchar%'
then nullif(
REGEXP_SUBSTR(external_type, '[0-9]+'),
'')::int
else null
end as character_maximum_length,
case
when external_type like 'numeric%'
then nullif(
SPLIT_PART(REGEXP_SUBSTR(external_type, '[0-9,]+'), ',', 1),
'')::int
else null
end as numeric_precision,
case
when external_type like 'numeric%'
then nullif(
SPLIT_PART(REGEXP_SUBSTR(external_type, '[0-9,]+'), ',', 2),
'')::int
else null
end as numeric_scale
from
pg_catalog.svv_external_columns
where
schemaname = '{{ relation.schema }}'
and tablename = '{{ relation.identifier }}'
),
unioned as (
select * from bound_views
union all
select * from unbound_views
union all
select * from external_views
)
select
column_name,
data_type,
character_maximum_length,
numeric_precision,
numeric_scale
from unioned
{% if relation.schema %}
where table_schema = '{{ relation.schema }}'
{% endif %}
order by ordinal_position
{% endcall %}
{% set table = load_result('get_columns_in_relation').table %}
{{ return(sql_convert_columns_in_relation(table)) }}
{% endmacro %}
{% macro redshift__list_relations_without_caching(schema_relation) %}
{% call statement('list_relations_without_caching', fetch_result=True) -%}
select
table_catalog as database,
table_name as name,
table_schema as schema,
'table' as type
from information_schema.tables
where table_schema ilike '{{ schema_relation.schema }}'
and table_type = 'BASE TABLE'
union all
select
table_catalog as database,
table_name as name,
table_schema as schema,
case
when view_definition ilike '%create materialized view%'
then 'materialized_view'
else 'view'
end as type
from information_schema.views
where table_schema ilike '{{ schema_relation.schema }}'
{% endcall %}
{{ return(load_result('list_relations_without_caching').table) }}
{% endmacro %}
{% macro redshift__information_schema_name(database) -%}
{{ return(postgres__information_schema_name(database)) }}
{%- endmacro %}
{% macro redshift__list_schemas(database) -%}
{{ return(postgres__list_schemas(database)) }}
{%- endmacro %}
{% macro redshift__check_schema_exists(information_schema, schema) -%}
{{ return(postgres__check_schema_exists(information_schema, schema)) }}
{%- endmacro %}
{% macro redshift__persist_docs(relation, model, for_relation, for_columns) -%}
{% if for_relation and config.persist_relation_docs() and model.description %}
{% do run_query(alter_relation_comment(relation, model.description)) %}
{% endif %}
{# Override: do not set column comments for LBVs #}
{% set is_lbv = config.get('materialized') == 'view' and config.get('bind') == false %}
{% if for_columns and config.persist_column_docs() and model.columns and not is_lbv %}
{% do run_query(alter_column_comment(relation, model.columns)) %}
{% endif %}
{% endmacro %}
{#
Copied from the postgres-adapter.
#}
{% macro escape_comment(comment) -%}
{% if comment is not string %}
{% do exceptions.raise_compiler_error('cannot escape a non-string: ' ~ comment) %}
{% endif %}
{%- set magic = '$dbt_comment_literal_block$' -%}
{%- if magic in comment -%}
{%- do exceptions.raise_compiler_error('The string ' ~ magic ~ ' is not allowed in comments.') -%}
{%- endif -%}
{{ magic }}{{ comment }}{{ magic }}
{%- endmacro %}
{% macro redshift__alter_relation_comment(relation, comment) %}
{%- set escaped_comment = escape_comment(comment) -%}
{%- set relation_type = 'view' if relation.type == 'materialized_view' else relation.type -%}
comment on {{ relation_type }} {{ relation }} is {{ escaped_comment }};
{% endmacro %}
{% macro redshift__alter_column_comment(relation, column_dict) %}
{% do return(postgres__alter_column_comment(relation, column_dict)) %}
{% endmacro %}
{% macro redshift__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}
{% if add_columns %}
{% for column in add_columns %}
{% set sql -%}
alter {{ relation.type }} {{ relation }} add column {{ column.name }} {{ column.data_type }}
{% endset %}
{% do run_query(sql) %}
{% endfor %}
{% endif %}
{% if remove_columns %}
{% for column in remove_columns %}
{% set sql -%}
alter {{ relation.type }} {{ relation }} drop column {{ column.name }}
{% endset %}
{% do run_query(sql) %}
{% endfor %}
{% endif %}
{% endmacro %}