diff --git a/integration_tests/models/plugins/snowflake/people_expression.sql b/integration_tests/models/plugins/snowflake/people_expression.sql new file mode 100644 index 0000000..677d119 --- /dev/null +++ b/integration_tests/models/plugins/snowflake/people_expression.sql @@ -0,0 +1,4 @@ +SELECT + {{ dbt_utils.star(from=ref('people')) }}, + split_part(email, '@', 2) as email_domain +FROM {{ ref('people') }} \ No newline at end of file diff --git a/integration_tests/models/plugins/snowflake/snowflake_external.yml b/integration_tests/models/plugins/snowflake/snowflake_external.yml index 943ce53..651513d 100644 --- a/integration_tests/models/plugins/snowflake/snowflake_external.yml +++ b/integration_tests/models/plugins/snowflake/snowflake_external.yml @@ -173,4 +173,31 @@ sources: - id - first_name - last_name - - email_alias \ No newline at end of file + - email_alias + + # test for column expression + - name: people_json_expression + external: *json-people + columns: + - name: id + data_type: int + - name: first_name + data_type: varchar(64) + - name: last_name + data_type: varchar(64) + - name: email + data_type: varchar(64) + - name: email_domain + data_type: varchar(64) + alias: EMAIL_DOMAIN + quote: true + expression: split_part(value:email::VARCHAR, '@', 2) + tests: + - dbt_utils.equality: + compare_model: ref('people_expression') + compare_columns: + - id + - first_name + - last_name + - email + - email_domain \ No newline at end of file diff --git a/macros/plugins/snowflake/create_external_table.sql b/macros/plugins/snowflake/create_external_table.sql index 7db5749..4032896 100644 --- a/macros/plugins/snowflake/create_external_table.sql +++ b/macros/plugins/snowflake/create_external_table.sql @@ -26,14 +26,25 @@ {%- endfor -%}{%- endif -%} {%- if not infer_schema -%} {%- for column in columns %} - {%- set column_alias = column.alias if column.alias else column.name %} - {%- set column_alias_quoted = adapter.quote(column_alias) if column.quote else column_alias %} {%- set column_quoted = adapter.quote(column.name) if column.quote else column.name %} + {%- set column_alias -%} + {%- if 'alias' in column and column.quote -%} + {{adapter.quote(column.alias)}} + {%- elif 'alias' in column -%} + {{column.alias}} + {%- else -%} + {{column_quoted}} + {%- endif -%} + {%- endset %} {%- set col_expression -%} - {%- set col_id = 'value:c' ~ loop.index if is_csv else 'value:' ~ column_quoted -%} - (case when is_null_value({{col_id}}) or lower({{col_id}}) = 'null' then null else {{col_id}} end) + {%- if column.expression -%} + {{column.expression}} + {%- else -%} + {%- set col_id = 'value:c' ~ loop.index if is_csv else 'value:' ~ column_alias -%} + (case when is_null_value({{col_id}}) or lower({{col_id}}) = 'null' then null else {{col_id}} end) + {%- endif -%} {%- endset %} - {{column_alias_quoted}} {{column.data_type}} as ({{col_expression}}::{{column.data_type}}) + {{column_alias}} {{column.data_type}} as ({{col_expression}}::{{column.data_type}}) {{- ',' if not loop.last -}} {% endfor %} {% else %} diff --git a/sample_sources/snowflake.yml b/sample_sources/snowflake.yml index 59ecde2..5498c31 100644 --- a/sample_sources/snowflake.yml +++ b/sample_sources/snowflake.yml @@ -32,6 +32,18 @@ sources: - name: etl_tstamp data_type: timestamp description: "Timestamp event began ETL" + - name: etl timestamp + # Use double-quoted identifiers for name and identifier + quote: true + # Specifying alias lets us rename etl timestamp to "etl_timestamp" + alias: etl_timestamp + data_type: timestamp + description: "Timestamp event began ETL with a double quoted identifier" + - name: etl_date + data_type: date + description: "Date event began ETL" + # Expressions can manipulate the variant value prior to casting to data_type. + expression: TRY_TO_DATE(VALUE:etl_tstamp::VARCHAR, 'YYYYMMDD') - name: contexts data_type: variant description: "Contexts attached to event by Tracker"