Edit on GitHub

sqlglot.optimizer.optimizer

 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 0x7ffa468d6f80>, <function pushdown_projections at 0x7ffa468d6170>, <function normalize at 0x7ffa46925cf0>, <function unnest_subqueries at 0x7ffa468d72e0>, <function pushdown_predicates at 0x7ffa468d5990>, <function optimize_joins at 0x7ffa468d5630>, <function eliminate_subqueries at 0x7ffa468d4820>, <function merge_subqueries at 0x7ffa468d48b0>, <function eliminate_joins at 0x7ffa46925ab0>, <function eliminate_ctes at 0x7ffa46925990>, <function quote_identifiers at 0x7ffa468d6950>, <function annotate_types at 0x7ffa46938c10>, <function canonicalize at 0x7ffa469252d0>, <function simplify at 0x7ffa46925ea0>), **kwargs) -> sqlglot.expressions.Expression:
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.