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 **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, 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 optimized = exp.maybe_parse(expression, dialect=dialect, copy=True) 86 for rule in rules: 87 # Find any additional rule parameters, beyond `expression` 88 rule_params = inspect.getfullargspec(rule).args 89 rule_kwargs = { 90 param: possible_kwargs[param] for param in rule_params if param in possible_kwargs 91 } 92 optimized = rule(optimized, **rule_kwargs) 93 94 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.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, 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 optimized = exp.maybe_parse(expression, dialect=dialect, copy=True) 87 for rule in rules: 88 # Find any additional rule parameters, beyond `expression` 89 rule_params = inspect.getfullargspec(rule).args 90 rule_kwargs = { 91 param: possible_kwargs[param] for param in rule_params if param in possible_kwargs 92 } 93 optimized = rule(optimized, **rule_kwargs) 94 95 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 atsqlgot.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.