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 | exp.Identifier] = None,
46    catalog: t.Optional[str | exp.Identifier] = 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: Union[sqlglot.expressions.Identifier, str, NoneType] = None, catalog: Union[sqlglot.expressions.Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.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>), **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    **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.