Edit on GitHub

sqlglot.optimizer.optimizer

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

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!
  • sql: Original SQL string for error highlighting. If not provided, errors will not include highlighting. Requires that the expression has position metadata from parsing.
  • *kwargs: If a rule has a keyword argument with a same name in *kwargs, it will be passed in.
Returns:

The optimized expression.