Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate date macros into timestamps.sql #5838

Merged
merged 40 commits into from
Sep 30, 2022

Conversation

colin-rogers-dbt
Copy link
Contributor

@colin-rogers-dbt colin-rogers-dbt commented Sep 14, 2022

resolves #5521

related PRs:

Description

Checklist

@colin-rogers-dbt colin-rogers-dbt requested a review from a team as a code owner September 14, 2022 16:22
@cla-bot cla-bot bot added the cla:yes label Sep 14, 2022
@github-actions
Copy link
Contributor

Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide.

@colin-rogers-dbt colin-rogers-dbt changed the title Consolidate date macros into dates.sql Consolidate date macros into timestamps.sql Sep 14, 2022
@colin-rogers-dbt colin-rogers-dbt self-assigned this Sep 14, 2022
@colin-rogers-dbt colin-rogers-dbt requested a review from a team as a code owner September 14, 2022 16:56
Copy link
Contributor

@gshank gshank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

Copy link
Contributor

@McKnight-42 McKnight-42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Copy link
Contributor

@jtcohen6 jtcohen6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very very happy to have these macros living in one place! Even if inconsistency must remain, to support backwards compatibility, we should aim to concentrate and cordon off that inconsistency as much as possible, highlight the contradictions, and provide clear guidance for net-new projects going forward.


I like the idea of trying to also incorporate the changes I recommended in #5521 (comment), which would enable the full removal of dbt_utils.current_timestamp by dbt-utils v1.0.


What do you think about deprecating date_function + sql_now()? That's the last tine in our fork of inconsistency.

Specifically, we could:

  • Stop making the base date_function an abstract method that every adapter must implement
  • Add a deprecation warning for anyone who calls sql_now in their project code. The deprecation message can say something like: "{{ sql_now }} and {{ adapter.date_function }} are deprecated, use {{ current_timestamp() }} or {{ now() }} instead." The sql_now function is very very old (Feature/first class pg #174), I don't know of anyone who actually uses it, but we're better safe than sorry. Our deprecations module shows a warning to the user, and it also fires an anonymous tracking event that can confirm for us whether anyone is actually using the thing.

Lastly, we'll want companion PRs in all our adapter plugins, and to test each of them thoroughly. I don't think our existing suite of functional tests is sensitive enough to catch subtly breaking changes in these macros.

@dbeatty10 - do you have thoughts on how we might write more sensitive automated tests? How did you pursue the work of comparing dbt.current_timestamp() and dbt_utils.current_timestamp() in dbt-labs/dbt-utils#597 (comment)?

@colin-rogers-dbt
Copy link
Contributor Author

I like the idea of trying to also incorporate the changes I recommended in #5521 (comment), which would enable the full removal of dbt_utils.current_timestamp by dbt-utils v1.0.

Will pull those changes in as well

What do you think about deprecating date_function + sql_now()? That's the last tine in our fork of inconsistency.

I like the idea but should probably be a follow on pr

Lastly, we'll want companion PRs in all our adapter plugins, and to test each of them thoroughly. I don't think our existing suite of functional tests is sensitive enough to catch subtly breaking changes in these macros.

I'm thinking I'll add a functional test into core and we can copy that one into the adapters

Copy link
Contributor

@dbeatty10 dbeatty10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colin-rogers-dbt I was working on some pytests in a totally separate PR and saw the code that Jerco mentioned to use yesterday that does schema comparisons. Linked inline.

tests/functional/timestamps/test_timestamps.py Outdated Show resolved Hide resolved
Copy link
Contributor

@jtcohen6 jtcohen6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very very happy to have this in for v1.3, and smooth the path for dbt-utils v1.0!

@colin-rogers-dbt
Copy link
Contributor Author

One easy way to test the backwards compatibility is just to compare the new SQL to the old SQL. If they are the same, then we are done.

Good idea, I've added an assertion to our functional tests to validate the compiled SQL

Copy link
Contributor

@dbeatty10 dbeatty10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two things I'd appreciate an additional set of eyes on before final approval (in order of importance):

  1. New implementation for default__current_timestamp discussed here
  2. Convention for test class names here and here

@jtcohen6 are you willing to give these a look (or suggest someone else)?


Other than that, this behavior looks as desired across postgres, snowflake, redshift, bigquery, spark, and databricks.

There are slight differences in the rendered SQL for the *_backcompat macros for the latter three vs. dbt_utils, but I don't think they make a functional difference.

Output for the curious

 

dbt-postgres

dbt compile --target postgres
postgres dbt.current_timestamp():
    now()

postgres dbt_utils.current_timestamp(): 
    current_timestamp::TIMESTAMP

postgres dbt.current_timestamp_backcompat(): 
    current_timestamp::TIMESTAMP

postgres dbt_utils.current_timestamp_in_utc(): 
    (current_timestamp at time zone 'utc')::TIMESTAMP

postgres dbt.current_timestamp_in_utc_backcompat(): 
    (current_timestamp at time zone 'utc')::TIMESTAMP

  

dbt-snowflake

dbt compile --target snowflake
snowflake dbt.current_timestamp():
    convert_timezone('UTC', current_timestamp())

snowflake dbt_utils.current_timestamp(): 
    current_timestamp::TIMESTAMP

snowflake dbt.current_timestamp_backcompat(): 
  current_timestamp::TIMESTAMP

snowflake dbt_utils.current_timestamp_in_utc(): 
    convert_timezone('UTC', 
    current_timestamp::TIMESTAMP
)::TIMESTAMP

snowflake dbt.current_timestamp_in_utc_backcompat(): 
  convert_timezone('UTC', 
  current_timestamp::TIMESTAMP
)::TIMESTAMP

  

dbt-redshift

dbt compile --target redshift
redshift dbt.current_timestamp():
    getdate()

redshift dbt_utils.current_timestamp(): 
    getdate()

redshift dbt.current_timestamp_backcompat(): getdate()
redshift dbt_utils.current_timestamp_in_utc(): 
    
    getdate()


redshift dbt.current_timestamp_in_utc_backcompat(): getdate()

  

dbt-bigquery

dbt compile --target bigquery
bigquery dbt.current_timestamp():
    CURRENT_TIMESTAMP()

bigquery dbt_utils.current_timestamp(): 
    current_timestamp

bigquery dbt.current_timestamp_backcompat(): CURRENT_TIMESTAMP()
bigquery dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp


bigquery dbt.current_timestamp_in_utc_backcompat(): CURRENT_TIMESTAMP()

  

dbt-spark

dbt compile --target spark
spark dbt.current_timestamp():
    current_timestamp()

spark dbt_utils.current_timestamp(): 
    current_timestamp::timestamp

spark dbt.current_timestamp_backcompat(): current_timestamp()
spark dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp::timestamp


spark dbt.current_timestamp_in_utc_backcompat(): current_timestamp()

  

dbt-databricks

dbt compile --target databricks
databricks dbt.current_timestamp():
    current_timestamp()

databricks dbt_utils.current_timestamp(): 
    current_timestamp::timestamp

databricks dbt.current_timestamp_backcompat(): current_timestamp()
databricks dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp::timestamp


databricks dbt.current_timestamp_in_utc_backcompat(): current_timestamp()

 

Copy link
Contributor

@dbeatty10 dbeatty10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colin-rogers-dbt Here's what we still need to do prior to approving this:

  1. Restore the implementation of default__current_timestamp. Rationale provided in the comments.
  2. PRs in dbt-snowflake and dbt-redshift need to be approved. There are code suggestions provided to unblock each.
  3. @gshank question for you: this PR has a new class named BaseCurrentTimestamps. There are PRs to add this as a test case for dbt-snowflake and dbt-redshift, but there are not PRs that add this test for dbt-bigquery and dbt-spark. Are there scenarios in which we don't add new test classes to all adapters?

Once those are done, I'll re-run this manual testing across the following adapters as additional confirmation: postgres, snowflake, redshift, bigquery, spark, and databricks.

Comment on lines 5 to 7
{% macro default__current_timestamp() %}
current_timestamp
{% endmacro %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unblocking this PR

I don't think your change is needed to accomplish the purposes of this back compatibility PR, so let's leave the existing implementation as-is (but you can move it from the old file to its new file) like so:

Suggested change
{% macro default__current_timestamp() %}
current_timestamp
{% endmacro %}
{% macro default__current_timestamp() -%}
{{ exceptions.raise_not_implemented(
'current_timestamp macro not implemented for adapter '+adapter.type()) }}
{%- endmacro %}

Providing a path for innovation and change

You proposed change to current_timestamp seems like a reasonable one to propose, and you can raise it in a stand-alone PR.

@gshank
Copy link
Contributor

gshank commented Sep 30, 2022

Yes, we won't be implementing all adapter zone tests for all adapters. We did expect that everything in the "basic" directory would be a requirement for all adapters, but tests in the adapter zone outside of that are optional. Not all adapters implement all features.

@dbeatty10 dbeatty10 self-requested a review September 30, 2022 22:30
Copy link
Contributor

@dbeatty10 dbeatty10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good across all adapters 🎉

Also confirmed manually:

Output

 

dbt-postgres

dbt compile --target postgres
postgres dbt.current_timestamp():
    now()

postgres dbt_utils.current_timestamp(): 
    current_timestamp::TIMESTAMP

postgres dbt.current_timestamp_backcompat(): 
    current_timestamp::TIMESTAMP

postgres dbt_utils.current_timestamp_in_utc(): 
    (current_timestamp at time zone 'utc')::TIMESTAMP

postgres dbt.current_timestamp_in_utc_backcompat(): 
    (current_timestamp at time zone 'utc')::TIMESTAMP

  

dbt-snowflake

dbt compile --target snowflake
snowflake dbt.current_timestamp():
    convert_timezone('UTC', current_timestamp())

snowflake dbt_utils.current_timestamp(): 
    current_timestamp::TIMESTAMP

snowflake dbt.current_timestamp_backcompat(): 
  current_timestamp::TIMESTAMP

snowflake dbt_utils.current_timestamp_in_utc(): 
    convert_timezone('UTC', 
    current_timestamp::TIMESTAMP
)::TIMESTAMP

snowflake dbt.current_timestamp_in_utc_backcompat(): 
  convert_timezone('UTC', 
  current_timestamp::TIMESTAMP
)::TIMESTAMP

  

dbt-redshift

dbt compile --target redshift
redshift dbt.current_timestamp():
    getdate()

redshift dbt_utils.current_timestamp(): 
    getdate()

redshift dbt.current_timestamp_backcompat(): getdate()
redshift dbt_utils.current_timestamp_in_utc(): 
    
    getdate()


redshift dbt.current_timestamp_in_utc_backcompat(): getdate()

  

dbt-bigquery

dbt compile --target bigquery
bigquery dbt.current_timestamp():
    CURRENT_TIMESTAMP()

bigquery dbt_utils.current_timestamp(): 
    current_timestamp

bigquery dbt.current_timestamp_backcompat(): current_timestamp
bigquery dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp


bigquery dbt.current_timestamp_in_utc_backcompat(): current_timestamp

  

dbt-spark

dbt compile --target spark
spark dbt.current_timestamp():
    CURRENT_TIMESTAMP()

spark dbt_utils.current_timestamp(): 
    current_timestamp::timestamp

spark dbt.current_timestamp_backcompat(): 
    current_timestamp::timestamp

spark dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp::timestamp


spark dbt.current_timestamp_in_utc_backcompat(): 
    current_timestamp::timestamp

  

dbt-databricks

dbt compile --target databricks
databricks dbt.current_timestamp():
    CURRENT_TIMESTAMP()

databricks dbt_utils.current_timestamp(): 
    current_timestamp::timestamp

databricks dbt.current_timestamp_backcompat(): 
    current_timestamp::timestamp

databricks dbt_utils.current_timestamp_in_utc(): 
    
    current_timestamp::timestamp


databricks dbt.current_timestamp_in_utc_backcompat(): 
    current_timestamp::timestamp

 

@colin-rogers-dbt colin-rogers-dbt merged commit a79960f into main Sep 30, 2022
@colin-rogers-dbt colin-rogers-dbt deleted the consolidate_timestamp_logic branch September 30, 2022 22:33
github-actions bot pushed a commit that referenced this pull request Oct 3, 2022
* Consolidate date macros into dates.sql

* rename to timestamps.sql

* fix whitespace + add changie

* cleanup macros and add testing

* fix whitespace

* remove now macro

* fix functional test

* remove local config

* make snowflake backwards compat return utc

* move timestamps to adaptor base tests

* move backcompat macros to respective adapters

* change timestamp param to source_timestamp

* move timestamps.py to utils

* update changie.yaml

* make expected schema a fixture

* formatting

* add debug message to assert

* fix changie.yaml

* Update tests/adapter/dbt/tests/adapter/utils/test_timestamps.py

Co-authored-by: Doug Beatty <[email protected]>

* Update plugins/postgres/dbt/include/postgres/macros/timestamps.sql

Co-authored-by: Doug Beatty <[email protected]>

* Update .changie.yaml

* add backcompat utc

* remove current_timestamp_in_utc

* remove convert_timezone

* add _in_utc_backcompat

* fix macro_calls typo

* add expected sql validation to test_timestamps

* make expected_sql optional

* improve sql check string comparison test

* remove extraneous test file

* add timestamp casting back

* Update plugins/postgres/dbt/include/postgres/macros/adapters.sql

Co-authored-by: Doug Beatty <[email protected]>

* add check_relation_has_expected_schema to comments

* fix whitespace

* remove default impl of current_timestamp

Co-authored-by: Doug Beatty <[email protected]>
(cherry picked from commit a79960f)
leahwicz added a commit that referenced this pull request Oct 3, 2022
* Consolidate date macros into dates.sql

* rename to timestamps.sql

* fix whitespace + add changie

* cleanup macros and add testing

* fix whitespace

* remove now macro

* fix functional test

* remove local config

* make snowflake backwards compat return utc

* move timestamps to adaptor base tests

* move backcompat macros to respective adapters

* change timestamp param to source_timestamp

* move timestamps.py to utils

* update changie.yaml

* make expected schema a fixture

* formatting

* add debug message to assert

* fix changie.yaml

* Update tests/adapter/dbt/tests/adapter/utils/test_timestamps.py

Co-authored-by: Doug Beatty <[email protected]>

* Update plugins/postgres/dbt/include/postgres/macros/timestamps.sql

Co-authored-by: Doug Beatty <[email protected]>

* Update .changie.yaml

* add backcompat utc

* remove current_timestamp_in_utc

* remove convert_timezone

* add _in_utc_backcompat

* fix macro_calls typo

* add expected sql validation to test_timestamps

* make expected_sql optional

* improve sql check string comparison test

* remove extraneous test file

* add timestamp casting back

* Update plugins/postgres/dbt/include/postgres/macros/adapters.sql

Co-authored-by: Doug Beatty <[email protected]>

* add check_relation_has_expected_schema to comments

* fix whitespace

* remove default impl of current_timestamp

Co-authored-by: Doug Beatty <[email protected]>
(cherry picked from commit a79960f)

Co-authored-by: colin-rogers-dbt <[email protected]>
Co-authored-by: leahwicz <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CT-895] [Spike] Consolidate current_timestamp & associates
6 participants