Table name containing the restricted keyword "case" triggers an error
Closed this issue · 4 comments
Describe the bug
The following SQL query:
with foo as (
select 1 from database.schema.case
)
select * from foo;
while valid (at least in Snowflake SQL), will make sqlfmt error with:
sqlfmt encountered an error: Closing bracket ')' found at 51 does not match last opened bracket 'case' found at 46.
It seems to be because the table name case
is also a reserved SQL keyword - but nonetheless allowed as a table name for certain databases. Interestingly, it only happens in a CTE, it works when running on the simpler
select 1 from database.schema.case;
To Reproduce
See above.
Expected behavior
Formatting/checking does not raise an error.
Actual behavior
See above.
Additional context
$ sqlfmt --version
sqlfmt, version 0.21.3
What is the output of pip list
(or pipx list
if you installed using pipx)?
n/a, let me know if that's needed.
Thanks for the report; would need to update the parser logic to support this.
The workaround is to quote it (which seems like a good idea anyway:
with foo as (
select 1 from database.schema."case"
)
select * from foo;
Indeed! However I found this bug in SQL auto-generated by dbt: https://github.com/dbt-labs/dbt-utils?tab=readme-ov-file#recency-source which makes it hard to add quotes without changing the implementation upstream.
It is not blocking me however, as I do have workarounds. Thanks for the quick reply and the great tool!
I suggest having sqlfmt ignore your target
directory and other generated code. Docs for that are here:
https://docs.sqlfmt.com/integrations/dbt
Just looked into this a little; Postgres, along with the '23, '16, and '92 ANSI standards consider case
a reserved keyword. What they don't specify this that your code totally runs on Postgres:
create table "case" as select 1;
with foo as (
select * from public.case
)
select * from foo;
Even select
, with
, and other very-reserved words work in place of case
.
MySQL also runs your code, and they are explicit that you can use reserved keywords without quoting if they are qualified identifiers (preceded with a period). Snowflake seems unusual in its permissiveness with keywords.
So obviously this doesn't just impact snowflake and case
-- need to re-think tokenizing any keywords and first check if they a preceded by a period.