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

Add initial Redshift support #1641

Merged
merged 3 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 12 additions & 4 deletions docs/source/dialects.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,20 @@ PostgreSQL
----------

This is based around the `PostgreSQL spec`_. Many other SQL instances are often
based on PostreSQL syntax. If you're running `AWS Redshift`_ or `Greenplum`_
this is the dialect to use (until someone makes a specific dialect).
based on PostreSQL syntax. If you're running an unsupported dialect, then
this is often the dialect to use (until someone makes a specific dialect).

.. _`PostgreSQL spec`: https://www.postgresql.org/docs/9.6/reference.html
.. _`AWS Redshift`: https://aws.amazon.com/redshift/
.. _`Greenplum`: https://greenplum.org/

.. _redshift_dialect_ref:

Redshift
----------


The dialect for `Amazon Redshift`_.

.. _`Amazon Redshift`: https://aws.amazon.com/redshift/

.. _snowflake_dialect_ref:

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def read(*names, **kwargs):
"hive",
"mysql",
"postgres",
"redshift",
"snowflake",
"sqlite",
"teradata",
Expand Down
9 changes: 5 additions & 4 deletions src/sqlfluff/core/dialects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
_dialect_lookup = {
"ansi": ("dialect_ansi", "ansi_dialect"),
"bigquery": ("dialect_bigquery", "bigquery_dialect"),
"exasol": ("dialect_exasol", "exasol_dialect"),
"hive": ("dialect_hive", "hive_dialect"),
"mysql": ("dialect_mysql", "mysql_dialect"),
"teradata": ("dialect_teradata", "teradata_dialect"),
"postgres": ("dialect_postgres", "postgres_dialect"),
"redshift": ("dialect_redshift", "redshift_dialect"),
"snowflake": ("dialect_snowflake", "snowflake_dialect"),
"exasol": ("dialect_exasol", "exasol_dialect"),
"tsql": ("dialect_tsql", "tsql_dialect"),
"hive": ("dialect_hive", "hive_dialect"),
"sqlite": ("dialect_sqlite", "sqlite_dialect"),
"teradata": ("dialect_teradata", "teradata_dialect"),
"tsql": ("dialect_tsql", "tsql_dialect"),
}

_legacy_dialects = {
Expand Down
56 changes: 56 additions & 0 deletions src/sqlfluff/dialects/dialect_redshift.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""The Amazon Redshift dialect.

This is based on postgres dialect, since it was initially based off of Postgres 8.
We should monitor in future and see if it should be rebased off of ANSI
"""

from sqlfluff.core.parser import (
OneOf,
BaseSegment,
)

from sqlfluff.core.dialects import load_raw_dialect

from sqlfluff.dialects.dialect_redshift_keywords import (
redshift_reserved_keywords,
redshift_unreserved_keywords,
)


postgres_dialect = load_raw_dialect("postgres")
ansi_dialect = load_raw_dialect("ansi")

redshift_dialect = postgres_dialect.copy_as("redshift")

# Set Keywords
redshift_dialect.sets("unreserved_keywords").clear()
redshift_dialect.sets("unreserved_keywords").update(
[n.strip().upper() for n in redshift_unreserved_keywords.split("\n")]
)

redshift_dialect.sets("reserved_keywords").clear()
redshift_dialect.sets("reserved_keywords").update(
[n.strip().upper() for n in redshift_reserved_keywords.split("\n")]
)


@redshift_dialect.segment(replace=True)
class DateAddFunctionNameSegment(BaseSegment):
"""DATEADD function name segment.

Override to support DATEDIFF as well
"""

type = "function_name"
match_grammar = OneOf("DATEADD", "DATEDIFF")


@redshift_dialect.segment(replace=True)
class FunctionSegment(BaseSegment):
"""A scalar or aggregate function.

Revert back to the ANSI definition to support ignore nulls
"""

type = "function"
match_grammar = ansi_dialect.get_segment("FunctionSegment").match_grammar.copy()