Edit on GitHub

# sqlglot.optimizer.optimizer

View Source

     1from __future__ import annotations
     2
     3import typing as t
     4
     5import sqlglot
     6from sqlglot import Schema, exp
     7from sqlglot.dialects.dialect import DialectType
     8from sqlglot.optimizer.annotate_types import annotate_types
     9from sqlglot.optimizer.canonicalize import canonicalize
    10from sqlglot.optimizer.eliminate_ctes import eliminate_ctes
    11from sqlglot.optimizer.eliminate_joins import eliminate_joins
    12from sqlglot.optimizer.eliminate_subqueries import eliminate_subqueries
    13from sqlglot.optimizer.merge_subqueries import merge_subqueries
    14from sqlglot.optimizer.normalize import normalize
    15from sqlglot.optimizer.optimize_joins import optimize_joins
    16from sqlglot.optimizer.pushdown_predicates import pushdown_predicates
    17from sqlglot.optimizer.pushdown_projections import pushdown_projections
    18from sqlglot.optimizer.qualify import qualify
    19from sqlglot.optimizer.qualify_columns import quote_identifiers
    20from sqlglot.optimizer.simplify import simplify
    21from sqlglot.optimizer.unnest_subqueries import unnest_subqueries
    22from sqlglot.schema import ensure_schema
    23
    24RULES = (
    25    qualify,
    26    pushdown_projections,
    27    normalize,
    28    unnest_subqueries,
    29    pushdown_predicates,
    30    optimize_joins,
    31    eliminate_subqueries,
    32    merge_subqueries,
    33    eliminate_joins,
    34    eliminate_ctes,
    35    quote_identifiers,
    36    annotate_types,
    37    canonicalize,
    38    simplify,
    39)
    40
    41
    42def optimize(
    43    expression: str | exp.Expression,
    44    schema: t.Optional[dict | Schema] = None,
    45    db: t.Optional[str] = None,
    46    catalog: t.Optional[str] = None,
    47    dialect: DialectType = None,
    48    rules: t.Sequence[t.Callable] = RULES,
    49    **kwargs,
    50) -> exp.Expression:
    51    """
    52    Rewrite a sqlglot AST into an optimized form.
    53
    54    Args:
    55        expression: expression to optimize
    56        schema: database schema.
    57            This can either be an instance of `sqlglot.optimizer.Schema` or a mapping in one of
    58            the following forms:
    59                1. {table: {col: type}}
    60                2. {db: {table: {col: type}}}
    61                3. {catalog: {db: {table: {col: type}}}}
    62            If no schema is provided then the default schema defined at `sqlgot.schema` will be used
    63        db: specify the default database, as might be set by a `USE DATABASE db` statement
    64        catalog: specify the default catalog, as might be set by a `USE CATALOG c` statement
    65        dialect: The dialect to parse the sql string.
    66        rules: sequence of optimizer rules to use.
    67            Many of the rules require tables and columns to be qualified.
    68            Do not remove `qualify` from the sequence of rules unless you know what you're doing!
    69        **kwargs: If a rule has a keyword argument with a same name in **kwargs, it will be passed in.
    70
    71    Returns:
    72        The optimized expression.
    73    """
    74    schema = ensure_schema(schema or sqlglot.schema, dialect=dialect)
    75    possible_kwargs = {
    76        "db": db,
    77        "catalog": catalog,
    78        "schema": schema,
    79        "dialect": dialect,
    80        "isolate_tables": True,  # needed for other optimizations to perform well
    81        "quote_identifiers": False,
    82        **kwargs,
    83    }
    84
    85    expression = exp.maybe_parse(expression, dialect=dialect, copy=True)
    86    for rule in rules:
    87        # Find any additional rule parameters, beyond `expression`
    88        rule_params = rule.__code__.co_varnames
    89        rule_kwargs = {
    90            param: possible_kwargs[param] for param in rule_params if param in possible_kwargs
    91        }
    92        expression = rule(expression, **rule_kwargs)
    93
    94    return t.cast(exp.Expression, expression)

RULES = (<function qualify>, <function pushdown_projections>, <function normalize>, <function unnest_subqueries>, <function pushdown_predicates>, <function optimize_joins>, <function eliminate_subqueries>, <function merge_subqueries>, <function eliminate_joins>, <function eliminate_ctes>, <function quote_identifiers>, <function annotate_types>, <function canonicalize>, <function simplify>)
def optimize( expression: str | sqlglot.expressions.Expression, schema: Union[dict, sqlglot.schema.Schema, NoneType] = None, db: Optional[str] = None, catalog: Optional[str] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, rules: Sequence[Callable] = (<function qualify at 0x7f140cc2f9a0>, <function pushdown_projections at 0x7f140cc2eb90>, <function normalize at 0x7f140cbea560>, <function unnest_subqueries at 0x7f140cc2fd00>, <function pushdown_predicates at 0x7f140cc2e3b0>, <function optimize_joins at 0x7f140cc2dfc0>, <function eliminate_subqueries at 0x7f140cc2d1b0>, <function merge_subqueries at 0x7f140cc2d240>, <function eliminate_joins at 0x7f140cbea290>, <function eliminate_ctes at 0x7f140cbea170>, <function quote_identifiers at 0x7f140cc2f370>, <function annotate_types at 0x7f140cbf9360>, <function canonicalize at 0x7f140cbe9ab0>, <function simplify at 0x7f140cbea710>), **kwargs) -> sqlglot.expressions.Expression: View Source

    43def optimize(
    44    expression: str | exp.Expression,
    45    schema: t.Optional[dict | Schema] = None,
    46    db: t.Optional[str] = None,
    47    catalog: t.Optional[str] = None,
    48    dialect: DialectType = None,
    49    rules: t.Sequence[t.Callable] = RULES,
    50    **kwargs,
    51) -> exp.Expression:
    52    """
    53    Rewrite a sqlglot AST into an optimized form.
    54
    55    Args:
    56        expression: expression to optimize
    57        schema: database schema.
    58            This can either be an instance of `sqlglot.optimizer.Schema` or a mapping in one of
    59            the following forms:
    60                1. {table: {col: type}}
    61                2. {db: {table: {col: type}}}
    62                3. {catalog: {db: {table: {col: type}}}}
    63            If no schema is provided then the default schema defined at `sqlgot.schema` will be used
    64        db: specify the default database, as might be set by a `USE DATABASE db` statement
    65        catalog: specify the default catalog, as might be set by a `USE CATALOG c` statement
    66        dialect: The dialect to parse the sql string.
    67        rules: sequence of optimizer rules to use.
    68            Many of the rules require tables and columns to be qualified.
    69            Do not remove `qualify` from the sequence of rules unless you know what you're doing!
    70        **kwargs: If a rule has a keyword argument with a same name in **kwargs, it will be passed in.
    71
    72    Returns:
    73        The optimized expression.
    74    """
    75    schema = ensure_schema(schema or sqlglot.schema, dialect=dialect)
    76    possible_kwargs = {
    77        "db": db,
    78        "catalog": catalog,
    79        "schema": schema,
    80        "dialect": dialect,
    81        "isolate_tables": True,  # needed for other optimizations to perform well
    82        "quote_identifiers": False,
    83        **kwargs,
    84    }
    85
    86    expression = exp.maybe_parse(expression, dialect=dialect, copy=True)
    87    for rule in rules:
    88        # Find any additional rule parameters, beyond `expression`
    89        rule_params = rule.__code__.co_varnames
    90        rule_kwargs = {
    91            param: possible_kwargs[param] for param in rule_params if param in possible_kwargs
    92        }
    93        expression = rule(expression, **rule_kwargs)
    94
    95    return t.cast(exp.Expression, expression)

Rewrite a sqlglot AST into an optimized form.

###### Arguments:

- expression: expression to optimize
- schema: database schema. This can either be an instance of `sqlglot.optimizer.Schema` or a mapping in one of the following forms: 1. {table: {col: type}} 2. {db: {table: {col: type}}} 3. {catalog: {db: {table: {col: type}}}} If no schema is provided then the default schema defined at `sqlgot.schema` will be used
- db: specify the default database, as might be set by a `USE DATABASE db` statement
- catalog: specify the default catalog, as might be set by a `USE CATALOG c` statement
- dialect: The dialect to parse the sql string.
- rules: sequence of optimizer rules to use. Many of the rules require tables and columns to be qualified. Do not remove `qualify` from the sequence of rules unless you know what you're doing!
- *kwargs: If a rule has a keyword argument with a same name in *kwargs, it will be passed in.

###### Returns:

> The optimized expression.