11{% macro bq_generate_incremental_insert_overwrite_build_sql(
2- tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions
2+ tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn
33) %}
44 {% if partition_by is none %}
55 {% set missing_partition_msg - %}
99 {% endif %}
1010
1111 {% set build_sql = bq_insert_overwrite_sql(
12- tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions
12+ tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn
1313 ) %}
1414
1515 {{ return(build_sql) }}
3838{% endmacro %}
3939
4040{% macro bq_insert_overwrite_sql(
41- tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions
41+ tmp_relation, target_relation, sql, unique_key, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn
4242) %}
4343 {% if partitions is not none and partitions != [] %} {# static #}
44- {{ bq_static_insert_overwrite_sql(tmp_relation, target_relation, sql, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions) }}
44+ {{ bq_static_insert_overwrite_sql(tmp_relation, target_relation, sql, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn ) }}
4545 {% else %} {# dynamic #}
46- {{ bq_dynamic_insert_overwrite_sql(tmp_relation, target_relation, sql, unique_key, partition_by, dest_columns, tmp_relation_exists, copy_partitions) }}
46+ {{ bq_dynamic_insert_overwrite_sql(tmp_relation, target_relation, sql, unique_key, partition_by, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn ) }}
4747 {% endif %}
4848{% endmacro %}
4949
5050{% macro bq_static_insert_overwrite_sql(
51- tmp_relation, target_relation, sql, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions
51+ tmp_relation, target_relation, sql, partition_by, partitions, dest_columns, tmp_relation_exists, copy_partitions, insert_overwrite_fn
5252) %}
5353
5454 {% set predicate - %}
8585 in the " temporary table exists" case, we save the model SQL result as a temp table first, wherein the
8686 sql_header is included by the create_table_as macro.
8787 # }
88- -- 1. run the merge statement
89- {{ get_insert_overwrite_merge_sql(target_relation, source_sql, dest_columns, [predicate], include_sql_header = not tmp_relation_exists) }};
88+
89+ {% if insert_overwrite_fn == ' delete+insert' %}
90+ -- 1. run insert_overwrite with delete+insert transaction strategy optimisation
91+ {{ bq_get_insert_overwrite_with_delete_and_insert_sql(target_relation, source_sql, dest_columns, [predicate], include_sql_header = not tmp_relation_exists) }};
92+ {% else %}
93+ -- 1. run insert_overwrite with merge strategy optimisation
94+ {{ get_insert_overwrite_merge_sql(target_relation, source_sql, dest_columns, [predicate], include_sql_header = not tmp_relation_exists) }};
95+ {% endif %}
9096
9197 {%- if tmp_relation_exists - %}
9298 -- 2. clean up the temp table
100106 tmp_relation, target_relation, sql, unique_key, partition_by, dest_columns, tmp_relation_exists, copy_partitions
101107 ) %}
102108 {%- if tmp_relation_exists is false - %}
103- {# We run temp table creation in a separated script to move to partitions copy if it doesn't already exist #}
109+ {# We run temp table creation in a separated script to move to partitions copy if it does not already exist #}
104110 {%- call statement(' create_tmp_relation_for_copy' , language= ' sql' ) - %}
105111 {{ bq_create_table_as(partition_by, True, tmp_relation, sql, ' sql' )
106112 }}
155161 from {{ tmp_relation }}
156162 );
157163
158- -- 3. run the merge statement
159- {{ get_insert_overwrite_merge_sql(target_relation, source_sql, dest_columns, [predicate]) }};
160-
164+ {% if insert_overwrite_fn == ' delete+insert' %}
165+ -- 3. run insert_overwrite with the delete+insert transaction strategy optimisation
166+ {{ bq_get_insert_overwrite_with_delete_and_insert_sql(target_relation, source_sql, dest_columns, [predicate]) }};
167+ {% else %}
168+ -- 3. run insert_overwrite with the merge strategy optimisation
169+ {{ get_insert_overwrite_merge_sql(target_relation, source_sql, dest_columns, [predicate]) }};
170+ {% endif %}
161171 -- 4. clean up the temp table
162172 drop table if exists {{ tmp_relation }}
163173
164174 {% endif %}
165175
166176{% endmacro %}
177+
178+
179+
180+ {% macro bq_get_insert_overwrite_with_delete_and_insert_sql(target, source, dest_columns, predicates, include_sql_header) - %}
181+ {%- set predicates = [] if predicates is none else [] + predicates - %}
182+ {%- set dest_cols_csv = get_quoted_csv(dest_columns | map(attribute= " name" )) - %}
183+ {%- set sql_header = config .get (' sql_header' , none) - %}
184+
185+ {{ sql_header if sql_header is not none and include_sql_header }}
186+
187+ begin
188+ begin transaction;
189+
190+ -- (as of Nov 2024)
191+ -- DELETE operations are free if the partition is a DATE
192+ -- * Not free if the partitions are granular (hourly, monthly)
193+ -- or some other conditions like subqueries and so on.
194+ delete from {{ target }} as DBT_INTERNAL_DEST
195+ where true
196+ {%- if predicates %}
197+ {% for predicate in predicates %}
198+ and {{ predicate }}
199+ {% endfor %}
200+ {%- endif - %};
201+
202+
203+ insert into {{ target }} ({{ dest_cols_csv }})
204+ (
205+ select {{ dest_cols_csv }}
206+ from {{ source }}
207+ );
208+
209+ commit transaction;
210+
211+ exception when error then
212+ raise using message = FORMAT(" Error: %s" , @@error .message );
213+ rollback transaction;
214+ end
215+ {% endmacro %}
0 commit comments