Skip to content

Commit

Permalink
Lift + shift for cross-db macros (dbt-labs#120)
Browse files Browse the repository at this point in the history
* Initialize lift + shift, dateadd + datediff

* Switch to alternative dev branches

* Lift and shift cross-database macros from dbt-utils

* Switch namespace from `dbt_utils` to `dbt`

* Remove conflicting definition of current_timestamp()

* Trim trailing whitespace

* Copy functional tests for cross-database macros from dbt-utils

* Remove references to other profiles

* Kick out the `current_timestamp` + `type_*` macros/tests

* Specify the namespace explicitly

* Duplicate default implementations into Redshift (to avoid inheritance issues)

* Remove branch identifiers

Co-authored-by: Jeremy Cohen <jeremy@dbtlabs.com>
  • Loading branch information
dbeatty10 and jtcohen6 authored Jun 17, 2022
1 parent 1240343 commit 81e5591
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 0 deletions.
6 changes: 6 additions & 0 deletions dbt/include/redshift/macros/utils/cast_bool_to_text.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% macro redshift__cast_bool_to_text(field) %}
case
when {{ field }} is true then 'true'
when {{ field }} is false then 'false'
end::text
{% endmacro %}
10 changes: 10 additions & 0 deletions dbt/include/redshift/macros/utils/dateadd.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{#-- redshift should use default instead of postgres --#}
{% macro redshift__dateadd(datepart, interval, from_date_or_timestamp) %}

dateadd(
{{ datepart }},
{{ interval }},
{{ from_date_or_timestamp }}
)

{% endmacro %}
10 changes: 10 additions & 0 deletions dbt/include/redshift/macros/utils/datediff.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{#-- redshift should use default instead of postgres --#}
{% macro redshift__datediff(first_date, second_date, datepart) -%}

datediff(
{{ datepart }},
{{ first_date }},
{{ second_date }}
)

{%- endmacro %}
8 changes: 8 additions & 0 deletions dbt/include/redshift/macros/utils/last_day.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{# redshift should use default instead of postgres #}
{% macro redshift__last_day(date, datepart) %}
cast(
{{dbt.dateadd('day', '-1',
dbt.dateadd(datepart, '1', dbt.date_trunc(datepart, date))
)}}
as date)
{% endmacro %}
7 changes: 7 additions & 0 deletions dbt/include/redshift/macros/utils/length.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% macro redshift__length(expression) %}

len(
{{ expression }}
)

{%- endmacro -%}
34 changes: 34 additions & 0 deletions dbt/include/redshift/macros/utils/listagg.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{# if there are instances of delimiter_text within your measure, you cannot include a limit_num #}
{% macro redshift__listagg(measure, delimiter_text, order_by_clause, limit_num) -%}

{% if limit_num -%}
{% set ns = namespace() %}
{% set ns.delimiter_text_regex = delimiter_text|trim("'") %}
{% set special_chars %}\,^,$,.,|,?,*,+,(,),[,],{,}{% endset %}
{%- for char in special_chars.split(',') -%}
{% set escape_char %}\\{{ char }}{% endset %}
{% set ns.delimiter_text_regex = ns.delimiter_text_regex|replace(char,escape_char) %}
{%- endfor -%}

{% set regex %}'([^{{ ns.delimiter_text_regex }}]+{{ ns.delimiter_text_regex }}){1,{{ limit_num - 1}}}[^{{ ns.delimiter_text_regex }}]+'{% endset %}
regexp_substr(
listagg(
{{ measure }},
{{ delimiter_text }}
)
{% if order_by_clause -%}
within group ({{ order_by_clause }})
{%- endif %}
,{{ regex }}
)
{%- else %}
listagg(
{{ measure }},
{{ delimiter_text }}
)
{% if order_by_clause -%}
within group ({{ order_by_clause }})
{%- endif %}
{%- endif %}

{%- endmacro %}
9 changes: 9 additions & 0 deletions dbt/include/redshift/macros/utils/split_part.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% macro redshift__split_part(string_text, delimiter_text, part_number) %}

{% if part_number >= 0 %}
{{ dbt.default__split_part(string_text, delimiter_text, part_number) }}
{% else %}
{{ dbt._split_part_negative(string_text, delimiter_text, part_number) }}
{% endif %}

{% endmacro %}
103 changes: 103 additions & 0 deletions tests/functional/adapter/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import pytest
from dbt.tests.adapter.utils.base_utils import BaseUtils
from dbt.tests.adapter.utils.test_any_value import BaseAnyValue
from dbt.tests.adapter.utils.test_bool_or import BaseBoolOr
from dbt.tests.adapter.utils.test_cast_bool_to_text import BaseCastBoolToText
from dbt.tests.adapter.utils.test_concat import BaseConcat
from dbt.tests.adapter.utils.test_dateadd import BaseDateAdd
from dbt.tests.adapter.utils.test_datediff import BaseDateDiff
from dbt.tests.adapter.utils.test_date_trunc import BaseDateTrunc
from dbt.tests.adapter.utils.test_escape_single_quotes import BaseEscapeSingleQuotesQuote
from dbt.tests.adapter.utils.test_escape_single_quotes import BaseEscapeSingleQuotesBackslash
from dbt.tests.adapter.utils.test_except import BaseExcept
from dbt.tests.adapter.utils.test_hash import BaseHash
from dbt.tests.adapter.utils.test_intersect import BaseIntersect
from dbt.tests.adapter.utils.test_last_day import BaseLastDay
from dbt.tests.adapter.utils.test_length import BaseLength
from dbt.tests.adapter.utils.test_listagg import BaseListagg
from dbt.tests.adapter.utils.test_position import BasePosition
from dbt.tests.adapter.utils.test_replace import BaseReplace
from dbt.tests.adapter.utils.test_right import BaseRight
from dbt.tests.adapter.utils.test_safe_cast import BaseSafeCast
from dbt.tests.adapter.utils.test_split_part import BaseSplitPart
from dbt.tests.adapter.utils.test_string_literal import BaseStringLiteral


class TestAnyValue(BaseAnyValue):
pass


class TestBoolOr(BaseBoolOr):
pass


class TestCastBoolToText(BaseCastBoolToText):
pass


class TestConcat(BaseConcat):
pass


class TestDateAdd(BaseDateAdd):
pass


class TestDateDiff(BaseDateDiff):
pass


class TestDateTrunc(BaseDateTrunc):
pass


class TestEscapeSingleQuotes(BaseEscapeSingleQuotesQuote):
pass


class TestExcept(BaseExcept):
pass


class TestHash(BaseHash):
pass


class TestIntersect(BaseIntersect):
pass


class TestLastDay(BaseLastDay):
pass


class TestLength(BaseLength):
pass


class TestListagg(BaseListagg):
pass


class TestPosition(BasePosition):
pass


class TestReplace(BaseReplace):
pass


class TestRight(BaseRight):
pass


class TestSafeCast(BaseSafeCast):
pass


class TestSplitPart(BaseSplitPart):
pass


class TestStringLiteral(BaseStringLiteral):
pass

0 comments on commit 81e5591

Please sign in to comment.