-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
accepted_values doesn't work properly when some of the values has the <'> (single quote) special character #10654
Comments
accepted_values
doesn't work properly when some of the values has the <'> (single quote) special character [Bug]
accepted_values
doesn't work properly when some of the values has the <'> (single quote) special character [Bug]
Thanks for reporting this @nicods-fr ! Easiest workaroundThe easiest way to solve this: just use the syntax of your database to escape the quotes. In your particular case with Postgres: models:
- name: my_model
columns:
- name: status
tests:
- accepted_values:
values:
- "will"
- "won''t" Possible solutionA possible way to solve this (but it looks like it would break anyone using the workaround above) would be to use the {{ dbt.string_literal(dbt.escape_single_quotes(value)) }}
accepted_values test with that modification (click to toggle visibility) |
Operating under the belief that contractions within But if we get a lot of feedback that this is high impact, we can take another look. |
I did fix it with a workaround, overriding the bugged test. I could fix it and start contributing if I get the time to read the contribution guide {#-/* Overriden DBT test */-#}
{%- macro test_accepted_values(model, column_name, values) -%}
{% if values is none or values|length == 0 %}
{{ exceptions.raise_compiler_error("values in accepted_values test cannot be Null or empty") }}
{% endif %}
{%- for val in values %}
{% if val is none %}
{{ exceptions.raise_compiler_error("Null is not a valid value in accepted_values.values") }}
{% endif %}
{%- endfor %}
WITH tested_values AS (
{%- for v_ in values %}
{% if not loop.first %} UNION ALL {% endif %}
SELECT '{{ v_.replace("'", "''") }}' AS expected_val {#/*"*/#}
{%- endfor %}
),
vals_in_col AS (
SELECT DISTINCT "{{column_name}}" FROM {{ model }}
),
sorted_vals_in_col AS (
SELECT "{{column_name}}"::TEXT AS actual_val FROM vals_in_col ORDER BY "{{column_name}}"
)
SELECT reality.actual_val AS bad_values
FROM sorted_vals_in_col reality
FULL JOIN tested_values expectation
ON reality.actual_val = expectation.expected_val
WHERE expectation.expected_val IS NULL AND reality.actual_val IS NOT NULL
{%- endmacro %} |
In my point of view, the proposed workaround is a bug. So anyone using it, should stop and fix their code. Also, the macro |
Thanks for providing the details of your workaround @nicods-fr 🤩
This is valid feedback! These macros originally came from the I buy into the point you are making, and opened dbt-labs/dbt-adapters#293 as a result. |
Is this a new bug in dbt-core?
Current Behavior
accepted_values doesn't work properly when some of the values has the <'> (single quote) special character
Expected Behavior
This test doesn't work, but it should:
Steps To Reproduce
Same as expected behavior
Relevant log output
No response
Environment
Which database adapter are you using with dbt?
postgres
Additional Context
No response
The text was updated successfully, but these errors were encountered: