Edit on GitHub

## Dialects

While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible SQL transpilation framework.

The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible.

Each SQL variation has its own `Dialect` subclass, extending the corresponding `Tokenizer`, `Parser` and `Generator` classes as needed.

### Implementing a custom Dialect

Creating a new SQL dialect may seem complicated at first, but it is actually quite simple in SQLGlot:

    from sqlglot import exp
    from sqlglot.dialects.dialect import Dialect
    from sqlglot.generator import Generator
    from sqlglot.tokens import Tokenizer, TokenType

    class Custom(Dialect):
        class Tokenizer(Tokenizer):
            QUOTES = ["'", '"']  # Strings can be delimited by either single or double quotes
            IDENTIFIERS = ["`"]  # Identifiers can be delimited by backticks

            # Associates certain meaningful words with tokens that capture their intent
            KEYWORDS = {
                **Tokenizer.KEYWORDS,
                "INT64": TokenType.BIGINT,
                "FLOAT64": TokenType.DOUBLE,
            }

        class Generator(Generator):
            # Specifies how AST nodes, i.e. subclasses of exp.Expression, should be converted into SQL
            TRANSFORMS = {
                exp.Array: lambda self, e: f"[{self.expressions(e)}]",
            }

            # Specifies how AST nodes representing data types should be converted into SQL
            TYPE_MAPPING = {
                exp.DataType.Type.TINYINT: "INT64",
                exp.DataType.Type.SMALLINT: "INT64",
                exp.DataType.Type.INT: "INT64",
                exp.DataType.Type.BIGINT: "INT64",
                exp.DataType.Type.DECIMAL: "NUMERIC",
                exp.DataType.Type.FLOAT: "FLOAT64",
                exp.DataType.Type.DOUBLE: "FLOAT64",
                exp.DataType.Type.BOOLEAN: "BOOL",
                exp.DataType.Type.TEXT: "STRING",
            }

The above example demonstrates how certain parts of the base `Dialect` class can be overridden to match a different specification. Even though it is a fairly realistic starting point, we strongly encourage the reader to study existing dialect implementations in order to understand how their various components can be modified, depending on the use-case.

View Source

     1# ruff: noqa: F401
     2"""
     3## Dialects
     4
     5While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult
     6to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible
     7SQL transpilation framework.
     8
     9The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible.
    10
    11Each SQL variation has its own `Dialect` subclass, extending the corresponding `Tokenizer`, `Parser` and `Generator`
    12classes as needed.
    13
    14### Implementing a custom Dialect
    15
    16Creating a new SQL dialect may seem complicated at first, but it is actually quite simple in SQLGlot:
    17
    18```python
    19from sqlglot import exp
    20from sqlglot.dialects.dialect import Dialect
    21from sqlglot.generator import Generator
    22from sqlglot.tokens import Tokenizer, TokenType
    23
    24
    25class Custom(Dialect):
    26    class Tokenizer(Tokenizer):
    27        QUOTES = ["'", '"']  # Strings can be delimited by either single or double quotes
    28        IDENTIFIERS = ["`"]  # Identifiers can be delimited by backticks
    29
    30        # Associates certain meaningful words with tokens that capture their intent
    31        KEYWORDS = {
    32            **Tokenizer.KEYWORDS,
    33            "INT64": TokenType.BIGINT,
    34            "FLOAT64": TokenType.DOUBLE,
    35        }
    36
    37    class Generator(Generator):
    38        # Specifies how AST nodes, i.e. subclasses of exp.Expression, should be converted into SQL
    39        TRANSFORMS = {
    40            exp.Array: lambda self, e: f"[{self.expressions(e)}]",
    41        }
    42
    43        # Specifies how AST nodes representing data types should be converted into SQL
    44        TYPE_MAPPING = {
    45            exp.DataType.Type.TINYINT: "INT64",
    46            exp.DataType.Type.SMALLINT: "INT64",
    47            exp.DataType.Type.INT: "INT64",
    48            exp.DataType.Type.BIGINT: "INT64",
    49            exp.DataType.Type.DECIMAL: "NUMERIC",
    50            exp.DataType.Type.FLOAT: "FLOAT64",
    51            exp.DataType.Type.DOUBLE: "FLOAT64",
    52            exp.DataType.Type.BOOLEAN: "BOOL",
    53            exp.DataType.Type.TEXT: "STRING",
    54        }
    55```
    56
    57The above example demonstrates how certain parts of the base `Dialect` class can be overridden to match a different
    58specification. Even though it is a fairly realistic starting point, we strongly encourage the reader to study existing
    59dialect implementations in order to understand how their various components can be modified, depending on the use-case.
    60
    61----
    62"""
    63
    64from sqlglot.dialects.athena import Athena
    65from sqlglot.dialects.bigquery import BigQuery
    66from sqlglot.dialects.clickhouse import ClickHouse
    67from sqlglot.dialects.databricks import Databricks
    68from sqlglot.dialects.dialect import Dialect, Dialects
    69from sqlglot.dialects.doris import Doris
    70from sqlglot.dialects.drill import Drill
    71from sqlglot.dialects.duckdb import DuckDB
    72from sqlglot.dialects.hive import Hive
    73from sqlglot.dialects.materialize import Materialize
    74from sqlglot.dialects.mysql import MySQL
    75from sqlglot.dialects.oracle import Oracle
    76from sqlglot.dialects.postgres import Postgres
    77from sqlglot.dialects.presto import Presto
    78from sqlglot.dialects.prql import PRQL
    79from sqlglot.dialects.redshift import Redshift
    80from sqlglot.dialects.risingwave import RisingWave
    81from sqlglot.dialects.snowflake import Snowflake
    82from sqlglot.dialects.spark import Spark
    83from sqlglot.dialects.spark2 import Spark2
    84from sqlglot.dialects.sqlite import SQLite
    85from sqlglot.dialects.starrocks import StarRocks
    86from sqlglot.dialects.tableau import Tableau
    87from sqlglot.dialects.teradata import Teradata
    88from sqlglot.dialects.trino import Trino
    89from sqlglot.dialects.tsql import TSQL