|
41 | 41 | {% endmacro %}
|
42 | 42 |
|
43 | 43 |
|
44 |
| -{% macro snapshot_staging_table(strategy, source_sql, target_relation) -%} |
| 44 | +{% macro oracle__snapshot_staging_table(strategy, source_sql, target_relation) -%} |
| 45 | + |
| 46 | + {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %} |
| 47 | + {% if strategy.hard_deletes == 'new_record' %} |
| 48 | + {% set new_scd_id = snapshot_hash_arguments([columns.dbt_scd_id, snapshot_get_time()]) %} |
| 49 | + {% endif %} |
45 | 50 |
|
46 | 51 | with snapshot_query as (
|
47 | 52 |
|
|
52 | 57 | snapshotted_data as (
|
53 | 58 |
|
54 | 59 | select {{ target_relation }}.*,
|
55 |
| - {{ strategy.unique_key }} as dbt_unique_key |
56 |
| - |
| 60 | + {{ unique_key_fields(strategy.unique_key) }} |
57 | 61 | from {{ target_relation }}
|
58 |
| - where dbt_valid_to is null |
59 |
| - |
| 62 | + where |
| 63 | + {% if config.get('dbt_valid_to_current') %} |
| 64 | + {% set source_unique_key = columns.dbt_valid_to | trim %} |
| 65 | + {% set target_unique_key = config.get('dbt_valid_to_current') | trim %} |
| 66 | + ( {{ equals(source_unique_key, target_unique_key) }} or {{ source_unique_key }} is null ) |
| 67 | + {% else %} |
| 68 | + {{ columns.dbt_valid_to }} is null |
| 69 | + {% endif %} |
60 | 70 | ),
|
61 | 71 |
|
62 | 72 | insertions_source_data as (
|
63 | 73 |
|
64 | 74 | select
|
65 | 75 | snapshot_query.*,
|
66 |
| - {{ strategy.unique_key }} as dbt_unique_key, |
67 |
| - {{ strategy.updated_at }} as dbt_updated_at, |
68 |
| - {{ strategy.updated_at }} as dbt_valid_from, |
69 |
| - nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as dbt_valid_to, |
70 |
| - {{ strategy.scd_id }} as dbt_scd_id |
| 76 | + {{ unique_key_fields(strategy.unique_key) }}, |
| 77 | + {{ strategy.updated_at }} as {{ columns.dbt_updated_at }}, |
| 78 | + {{ strategy.updated_at }} as {{ columns.dbt_valid_from }}, |
| 79 | + {{ oracle__get_dbt_valid_to_current(strategy, columns) }}, |
| 80 | + {{ strategy.scd_id }} as {{ columns.dbt_scd_id }} |
71 | 81 |
|
72 | 82 | from snapshot_query
|
73 | 83 | ),
|
|
76 | 86 |
|
77 | 87 | select
|
78 | 88 | snapshot_query.*,
|
79 |
| - {{ strategy.unique_key }} as dbt_unique_key, |
80 |
| - {{ strategy.updated_at }} as dbt_updated_at, |
81 |
| - {{ strategy.updated_at }} as dbt_valid_from, |
82 |
| - {{ strategy.updated_at }} as dbt_valid_to |
| 89 | + {{ unique_key_fields(strategy.unique_key) }}, |
| 90 | + {{ strategy.updated_at }} as {{ columns.dbt_updated_at }}, |
| 91 | + {{ strategy.updated_at }} as {{ columns.dbt_valid_from }}, |
| 92 | + {{ strategy.updated_at }} as {{ columns.dbt_valid_to }} |
83 | 93 |
|
84 | 94 | from snapshot_query
|
85 | 95 | ),
|
86 | 96 |
|
87 |
| - {%- if strategy.invalidate_hard_deletes %} |
| 97 | + {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %} |
88 | 98 |
|
89 | 99 | deletes_source_data as (
|
90 | 100 |
|
91 | 101 | select
|
92 | 102 | snapshot_query.*,
|
93 |
| - {{ strategy.unique_key }} as dbt_unique_key |
| 103 | + {{ unique_key_fields(strategy.unique_key) }} |
94 | 104 | from snapshot_query
|
95 | 105 | ),
|
96 | 106 | {% endif %}
|
|
100 | 110 | select
|
101 | 111 | 'insert' as dbt_change_type,
|
102 | 112 | source_data.*
|
| 113 | + {%- if strategy.hard_deletes == 'new_record' -%} |
| 114 | + ,'False' as {{ columns.dbt_is_deleted }} |
| 115 | + {%- endif %} |
103 | 116 |
|
104 | 117 | from insertions_source_data source_data
|
105 |
| - left outer join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key |
106 |
| - where snapshotted_data.dbt_unique_key is null |
107 |
| - or ( |
108 |
| - snapshotted_data.dbt_unique_key is not null |
109 |
| - and ( |
110 |
| - {{ strategy.row_changed }} |
111 |
| - ) |
| 118 | + left outer join snapshotted_data |
| 119 | + on {{ unique_key_join_on(strategy.unique_key, "snapshotted_data", "source_data") }} |
| 120 | + where {{ unique_key_is_null(strategy.unique_key, "snapshotted_data") }} |
| 121 | + or ({{ unique_key_is_not_null(strategy.unique_key, "snapshotted_data") }} and ({{ strategy.row_changed }}) |
| 122 | + |
112 | 123 | )
|
113 | 124 |
|
114 | 125 | ),
|
|
118 | 129 | select
|
119 | 130 | 'update' as dbt_change_type,
|
120 | 131 | source_data.*,
|
121 |
| - snapshotted_data.dbt_scd_id |
| 132 | + snapshotted_data.{{ columns.dbt_scd_id }} |
| 133 | + {%- if strategy.hard_deletes == 'new_record' -%} |
| 134 | + , snapshotted_data.{{ columns.dbt_is_deleted }} |
| 135 | + {%- endif %} |
122 | 136 |
|
123 | 137 | from updates_source_data source_data
|
124 |
| - join snapshotted_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key |
| 138 | + join snapshotted_data |
| 139 | + on {{ unique_key_join_on(strategy.unique_key, "snapshotted_data", "source_data") }} |
125 | 140 | where (
|
126 | 141 | {{ strategy.row_changed }}
|
127 | 142 | )
|
128 | 143 | )
|
129 | 144 |
|
130 |
| - {%- if strategy.invalidate_hard_deletes -%} |
| 145 | + {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' -%} |
131 | 146 | ,
|
132 | 147 |
|
133 | 148 | deletes as (
|
134 | 149 |
|
135 | 150 | select
|
136 | 151 | 'delete' as dbt_change_type,
|
137 | 152 | source_data.*,
|
138 |
| - {{ snapshot_get_time() }} as dbt_valid_from, |
139 |
| - {{ snapshot_get_time() }} as dbt_updated_at, |
140 |
| - {{ snapshot_get_time() }} as dbt_valid_to, |
141 |
| - snapshotted_data.dbt_scd_id |
| 153 | + {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }}, |
| 154 | + {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }}, |
| 155 | + {{ snapshot_get_time() }} as {{ columns.dbt_valid_to }}, |
| 156 | + snapshotted_data.{{ columns.dbt_scd_id }} |
| 157 | + {%- if strategy.hard_deletes == 'new_record' -%} |
| 158 | + , snapshotted_data.{{ columns.dbt_is_deleted }} |
| 159 | + {%- endif %} |
142 | 160 |
|
143 | 161 | from snapshotted_data
|
144 |
| - left join deletes_source_data source_data on snapshotted_data.dbt_unique_key = source_data.dbt_unique_key |
145 |
| - where source_data.dbt_unique_key is null |
| 162 | + left join deletes_source_data source_data |
| 163 | + on {{ unique_key_join_on(strategy.unique_key, "snapshotted_data", "source_data") }} |
| 164 | + where {{ unique_key_is_null(strategy.unique_key, "source_data") }} |
| 165 | + ) |
| 166 | + {%- endif %} |
| 167 | + |
| 168 | + {%- if strategy.hard_deletes == 'new_record' %} |
| 169 | + {% set source_sql_cols = get_column_schema_from_query(source_sql) %} |
| 170 | + , |
| 171 | + deletion_records as ( |
| 172 | + |
| 173 | + select |
| 174 | + 'insert' as dbt_change_type, |
| 175 | + {%- for col in source_sql_cols -%} |
| 176 | + snapshotted_data.{{ adapter.quote(col.column) }}, |
| 177 | + {% endfor -%} |
| 178 | + {%- if strategy.unique_key | is_list -%} |
| 179 | + {%- for key in strategy.unique_key -%} |
| 180 | + snapshotted_data.{{ key }} as dbt_unique_key_{{ loop.index }}, |
| 181 | + {% endfor -%} |
| 182 | + {%- else -%} |
| 183 | + snapshotted_data.dbt_unique_key as dbt_unique_key, |
| 184 | + {% endif -%} |
| 185 | + {{ snapshot_get_time() }} as {{ columns.dbt_valid_from }}, |
| 186 | + {{ snapshot_get_time() }} as {{ columns.dbt_updated_at }}, |
| 187 | + snapshotted_data.{{ columns.dbt_valid_to }} as {{ columns.dbt_valid_to }}, |
| 188 | + {{ new_scd_id }} as {{ columns.dbt_scd_id }}, |
| 189 | + 'True' as {{ columns.dbt_is_deleted }} |
| 190 | + from snapshotted_data |
| 191 | + left join deletes_source_data as source_data |
| 192 | + on {{ unique_key_join_on(strategy.unique_key, "snapshotted_data", "source_data") }} |
| 193 | + where {{ unique_key_is_null(strategy.unique_key, "source_data") }} |
| 194 | + |
146 | 195 | )
|
147 | 196 | {%- endif %}
|
148 | 197 |
|
149 | 198 | select * from insertions
|
150 | 199 | union all
|
151 | 200 | select * from updates
|
152 |
| - {%- if strategy.invalidate_hard_deletes %} |
| 201 | + {%- if strategy.hard_deletes == 'invalidate' or strategy.hard_deletes == 'new_record' %} |
153 | 202 | union all
|
154 | 203 | select * from deletes
|
155 | 204 | {%- endif %}
|
| 205 | + {%- if strategy.hard_deletes == 'new_record' %} |
| 206 | + union all |
| 207 | + select * from deletion_records |
| 208 | + {%- endif %} |
156 | 209 |
|
157 | 210 | {%- endmacro %}
|
158 | 211 |
|
159 | 212 |
|
160 | 213 |
|
161 |
| -{% macro build_snapshot_table(strategy, sql) %} |
| 214 | +{% macro oracle__build_snapshot_table(strategy, sql) %} |
| 215 | + {% set columns = config.get('snapshot_table_column_names') or get_snapshot_table_column_names() %} |
162 | 216 |
|
163 | 217 | select sbq.*,
|
164 |
| - {{ strategy.scd_id }} as dbt_scd_id, |
165 |
| - {{ strategy.updated_at }} as dbt_updated_at, |
166 |
| - {{ strategy.updated_at }} as dbt_valid_from, |
167 |
| - cast(nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}) as TIMESTAMP(9)) as dbt_valid_to |
| 218 | + {{ strategy.scd_id }} as {{ columns.dbt_scd_id }}, |
| 219 | + {{ strategy.updated_at }} as {{ columns.dbt_updated_at }}, |
| 220 | + {{ strategy.updated_at }} as {{ columns.dbt_valid_from }}, |
| 221 | + {{ oracle__get_dbt_valid_to_current(strategy, columns) }} |
| 222 | + {%- if strategy.hard_deletes == 'new_record' -%} |
| 223 | + , 'False' as {{ columns.dbt_is_deleted }} |
| 224 | + {% endif -%} |
168 | 225 | from (
|
169 | 226 | {{ sql }}
|
170 | 227 | ) sbq
|
|
239 | 296 | {% if not target_relation_exists %}
|
240 | 297 |
|
241 | 298 | {% set build_sql = build_snapshot_table(strategy, model['compiled_sql']) %}
|
| 299 | + {% set build_or_select_sql = build_sql %} |
242 | 300 | {% set final_sql = create_table_as(False, target_relation, build_sql) %}
|
243 | 301 |
|
244 | 302 | {% else %}
|
245 | 303 |
|
246 |
| - {{ adapter.valid_snapshot_target(target_relation) }} |
| 304 | + {% set columns = config.get("snapshot_table_column_names") or get_snapshot_table_column_names() %} |
247 | 305 |
|
| 306 | + {{ adapter.assert_valid_snapshot_target_given_strategy(target_relation, columns, strategy) }} |
| 307 | + |
| 308 | + {% set build_or_select_sql = snapshot_staging_table(strategy, sql, target_relation) %} |
248 | 309 | {% set staging_table = build_snapshot_staging_table(strategy, sql, target_relation) %}
|
249 | 310 |
|
250 | 311 | -- this may no-op if the database does not require column expansion
|
251 | 312 | {% do adapter.expand_target_column_types(from_relation=staging_table,
|
252 | 313 | to_relation=target_relation) %}
|
253 | 314 |
|
| 315 | + {% set remove_columns = ['dbt_change_type', 'DBT_CHANGE_TYPE', 'dbt_unique_key', 'DBT_UNIQUE_KEY'] %} |
| 316 | + {% if unique_key | is_list %} |
| 317 | + {% for key in strategy.unique_key %} |
| 318 | + {{ remove_columns.append('dbt_unique_key_' + loop.index|string) }} |
| 319 | + {{ remove_columns.append('DBT_UNIQUE_KEY_' + loop.index|string) }} |
| 320 | + {% endfor %} |
| 321 | + {% endif %} |
| 322 | + |
254 | 323 | {% set missing_columns = adapter.get_missing_columns(staging_table, target_relation)
|
255 |
| - | rejectattr('name', 'equalto', 'dbt_change_type') |
256 |
| - | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE') |
257 |
| - | rejectattr('name', 'equalto', 'dbt_unique_key') |
258 |
| - | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY') |
| 324 | + | rejectattr('name', 'in', remove_columns) |
259 | 325 | | list %}
|
260 | 326 |
|
261 | 327 | {% do create_columns(target_relation, missing_columns) %}
|
262 | 328 |
|
263 | 329 | {% set source_columns = adapter.get_columns_in_relation(staging_table)
|
264 |
| - | rejectattr('name', 'equalto', 'dbt_change_type') |
265 |
| - | rejectattr('name', 'equalto', 'DBT_CHANGE_TYPE') |
266 |
| - | rejectattr('name', 'equalto', 'dbt_unique_key') |
267 |
| - | rejectattr('name', 'equalto', 'DBT_UNIQUE_KEY') |
| 330 | + | rejectattr('name', 'in', remove_columns) |
268 | 331 | | list %}
|
269 | 332 |
|
270 | 333 | {% set quoted_source_columns = [] %}
|
|
281 | 344 |
|
282 | 345 | {% endif %}
|
283 | 346 |
|
| 347 | + {{ check_time_data_types(build_or_select_sql) }} |
| 348 | + |
284 | 349 | {% call statement('main') %}
|
285 | 350 | {{ final_sql }}
|
286 | 351 | {% endcall %}
|
|
305 | 370 | {% endmaterialization %}
|
306 | 371 |
|
307 | 372 | {% macro oracle__snapshot_hash_arguments(args) -%}
|
308 |
| - ORA_HASH({%- for arg in args -%} |
309 |
| - coalesce(cast({{ arg }} as varchar(50) ), '') |
| 373 | + STANDARD_HASH({%- for arg in args -%} |
| 374 | + coalesce(cast({{ arg }} as varchar(4000) ), '') |
310 | 375 | {% if not loop.last %} || '|' || {% endif %}
|
311 |
| - {%- endfor -%}) |
| 376 | + {%- endfor -%}, 'SHA256') |
312 | 377 | {%- endmacro %}
|
313 | 378 |
|
| 379 | +{% macro oracle__get_dbt_valid_to_current(strategy, columns) %} |
| 380 | + {% set dbt_valid_to_current = config.get('dbt_valid_to_current') or "CAST(null as TIMESTAMP(9)" %} |
| 381 | + coalesce(nullif({{ strategy.updated_at }}, {{ strategy.updated_at }}), {{dbt_valid_to_current}})) |
| 382 | + as {{ columns.dbt_valid_to }} |
| 383 | +{% endmacro %} |
| 384 | + |
0 commit comments