sqlglot.optimizer.qualify
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp 6from sqlglot.dialects.dialect import Dialect, DialectType 7from sqlglot.optimizer.isolate_table_selects import isolate_table_selects 8from sqlglot.optimizer.normalize_identifiers import normalize_identifiers 9from sqlglot.optimizer.qualify_columns import ( 10 qualify_columns as qualify_columns_func, 11 quote_identifiers as quote_identifiers_func, 12 validate_qualify_columns as validate_qualify_columns_func, 13) 14from sqlglot.optimizer.qualify_tables import qualify_tables 15from sqlglot.schema import Schema, ensure_schema 16 17 18def qualify( 19 expression: exp.Expression, 20 dialect: DialectType = None, 21 db: t.Optional[str] = None, 22 catalog: t.Optional[str] = None, 23 schema: t.Optional[dict | Schema] = None, 24 expand_alias_refs: bool = True, 25 expand_stars: bool = True, 26 infer_schema: t.Optional[bool] = None, 27 isolate_tables: bool = False, 28 qualify_columns: bool = True, 29 allow_partial_qualification: bool = False, 30 validate_qualify_columns: bool = True, 31 quote_identifiers: bool = True, 32 identify: bool = True, 33 canonicalize_table_aliases: bool = False, 34 on_qualify: t.Optional[t.Callable[[exp.Expression], None]] = None, 35 sql: t.Optional[str] = None, 36) -> exp.Expression: 37 """ 38 Rewrite sqlglot AST to have normalized and qualified tables and columns. 39 40 This step is necessary for all further SQLGlot optimizations. 41 42 Example: 43 >>> import sqlglot 44 >>> schema = {"tbl": {"col": "INT"}} 45 >>> expression = sqlglot.parse_one("SELECT col FROM tbl") 46 >>> qualify(expression, schema=schema).sql() 47 'SELECT "tbl"."col" AS "col" FROM "tbl" AS "tbl"' 48 49 Args: 50 expression: Expression to qualify. 51 db: Default database name for tables. 52 catalog: Default catalog name for tables. 53 schema: Schema to infer column names and types. 54 expand_alias_refs: Whether to expand references to aliases. 55 expand_stars: Whether to expand star queries. This is a necessary step 56 for most of the optimizer's rules to work; do not set to False unless you 57 know what you're doing! 58 infer_schema: Whether to infer the schema if missing. 59 isolate_tables: Whether to isolate table selects. 60 qualify_columns: Whether to qualify columns. 61 allow_partial_qualification: Whether to allow partial qualification. 62 validate_qualify_columns: Whether to validate columns. 63 quote_identifiers: Whether to run the quote_identifiers step. 64 This step is necessary to ensure correctness for case sensitive queries. 65 But this flag is provided in case this step is performed at a later time. 66 identify: If True, quote all identifiers, else only necessary ones. 67 canonicalize_table_aliases: Whether to use canonical aliases (_0, _1, ...) for all sources 68 instead of preserving table names. 69 on_qualify: Callback after a table has been qualified. 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 73 Returns: 74 The qualified expression. 75 """ 76 schema = ensure_schema(schema, dialect=dialect) 77 dialect = Dialect.get_or_raise(dialect) 78 79 expression = normalize_identifiers( 80 expression, 81 dialect=dialect, 82 store_original_column_identifiers=True, 83 ) 84 expression = qualify_tables( 85 expression, 86 db=db, 87 catalog=catalog, 88 dialect=dialect, 89 on_qualify=on_qualify, 90 canonicalize_table_aliases=canonicalize_table_aliases, 91 ) 92 93 if isolate_tables: 94 expression = isolate_table_selects(expression, schema=schema) 95 96 if qualify_columns: 97 expression = qualify_columns_func( 98 expression, 99 schema, 100 expand_alias_refs=expand_alias_refs, 101 expand_stars=expand_stars, 102 infer_schema=infer_schema, 103 allow_partial_qualification=allow_partial_qualification, 104 ) 105 106 if quote_identifiers: 107 expression = quote_identifiers_func(expression, dialect=dialect, identify=identify) 108 109 if validate_qualify_columns: 110 validate_qualify_columns_func(expression, sql=sql) 111 112 return expression
def
qualify( expression: sqlglot.expressions.Expression, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, db: Optional[str] = None, catalog: Optional[str] = None, schema: Union[dict, sqlglot.schema.Schema, NoneType] = None, expand_alias_refs: bool = True, expand_stars: bool = True, infer_schema: Optional[bool] = None, isolate_tables: bool = False, qualify_columns: bool = True, allow_partial_qualification: bool = False, validate_qualify_columns: bool = True, quote_identifiers: bool = True, identify: bool = True, canonicalize_table_aliases: bool = False, on_qualify: Optional[Callable[[sqlglot.expressions.Expression], NoneType]] = None, sql: Optional[str] = None) -> sqlglot.expressions.Expression:
19def qualify( 20 expression: exp.Expression, 21 dialect: DialectType = None, 22 db: t.Optional[str] = None, 23 catalog: t.Optional[str] = None, 24 schema: t.Optional[dict | Schema] = None, 25 expand_alias_refs: bool = True, 26 expand_stars: bool = True, 27 infer_schema: t.Optional[bool] = None, 28 isolate_tables: bool = False, 29 qualify_columns: bool = True, 30 allow_partial_qualification: bool = False, 31 validate_qualify_columns: bool = True, 32 quote_identifiers: bool = True, 33 identify: bool = True, 34 canonicalize_table_aliases: bool = False, 35 on_qualify: t.Optional[t.Callable[[exp.Expression], None]] = None, 36 sql: t.Optional[str] = None, 37) -> exp.Expression: 38 """ 39 Rewrite sqlglot AST to have normalized and qualified tables and columns. 40 41 This step is necessary for all further SQLGlot optimizations. 42 43 Example: 44 >>> import sqlglot 45 >>> schema = {"tbl": {"col": "INT"}} 46 >>> expression = sqlglot.parse_one("SELECT col FROM tbl") 47 >>> qualify(expression, schema=schema).sql() 48 'SELECT "tbl"."col" AS "col" FROM "tbl" AS "tbl"' 49 50 Args: 51 expression: Expression to qualify. 52 db: Default database name for tables. 53 catalog: Default catalog name for tables. 54 schema: Schema to infer column names and types. 55 expand_alias_refs: Whether to expand references to aliases. 56 expand_stars: Whether to expand star queries. This is a necessary step 57 for most of the optimizer's rules to work; do not set to False unless you 58 know what you're doing! 59 infer_schema: Whether to infer the schema if missing. 60 isolate_tables: Whether to isolate table selects. 61 qualify_columns: Whether to qualify columns. 62 allow_partial_qualification: Whether to allow partial qualification. 63 validate_qualify_columns: Whether to validate columns. 64 quote_identifiers: Whether to run the quote_identifiers step. 65 This step is necessary to ensure correctness for case sensitive queries. 66 But this flag is provided in case this step is performed at a later time. 67 identify: If True, quote all identifiers, else only necessary ones. 68 canonicalize_table_aliases: Whether to use canonical aliases (_0, _1, ...) for all sources 69 instead of preserving table names. 70 on_qualify: Callback after a table has been qualified. 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 74 Returns: 75 The qualified expression. 76 """ 77 schema = ensure_schema(schema, dialect=dialect) 78 dialect = Dialect.get_or_raise(dialect) 79 80 expression = normalize_identifiers( 81 expression, 82 dialect=dialect, 83 store_original_column_identifiers=True, 84 ) 85 expression = qualify_tables( 86 expression, 87 db=db, 88 catalog=catalog, 89 dialect=dialect, 90 on_qualify=on_qualify, 91 canonicalize_table_aliases=canonicalize_table_aliases, 92 ) 93 94 if isolate_tables: 95 expression = isolate_table_selects(expression, schema=schema) 96 97 if qualify_columns: 98 expression = qualify_columns_func( 99 expression, 100 schema, 101 expand_alias_refs=expand_alias_refs, 102 expand_stars=expand_stars, 103 infer_schema=infer_schema, 104 allow_partial_qualification=allow_partial_qualification, 105 ) 106 107 if quote_identifiers: 108 expression = quote_identifiers_func(expression, dialect=dialect, identify=identify) 109 110 if validate_qualify_columns: 111 validate_qualify_columns_func(expression, sql=sql) 112 113 return expression
Rewrite sqlglot AST to have normalized and qualified tables and columns.
This step is necessary for all further SQLGlot optimizations.
Example:
>>> import sqlglot >>> schema = {"tbl": {"col": "INT"}} >>> expression = sqlglot.parse_one("SELECT col FROM tbl") >>> qualify(expression, schema=schema).sql() 'SELECT "tbl"."col" AS "col" FROM "tbl" AS "tbl"'
Arguments:
- expression: Expression to qualify.
- db: Default database name for tables.
- catalog: Default catalog name for tables.
- schema: Schema to infer column names and types.
- expand_alias_refs: Whether to expand references to aliases.
- expand_stars: Whether to expand star queries. This is a necessary step for most of the optimizer's rules to work; do not set to False unless you know what you're doing!
- infer_schema: Whether to infer the schema if missing.
- isolate_tables: Whether to isolate table selects.
- qualify_columns: Whether to qualify columns.
- allow_partial_qualification: Whether to allow partial qualification.
- validate_qualify_columns: Whether to validate columns.
- quote_identifiers: Whether to run the quote_identifiers step. This step is necessary to ensure correctness for case sensitive queries. But this flag is provided in case this step is performed at a later time.
- identify: If True, quote all identifiers, else only necessary ones.
- canonicalize_table_aliases: Whether to use canonical aliases (_0, _1, ...) for all sources instead of preserving table names.
- on_qualify: Callback after a table has been qualified.
- sql: Original SQL string for error highlighting. If not provided, errors will not include highlighting. Requires that the expression has position metadata from parsing.
Returns:
The qualified expression.