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.Schemaor 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.schemawill be used - db: specify the default database, as might be set by a
USE DATABASE dbstatement - catalog: specify the default catalog, as might be set by a
USE CATALOG cstatement - 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
qualifyfrom 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.