Edit on GitHub

sqlglot.optimizer.isolate_table_selects

 1from __future__ import annotations
 2
 3import typing as t
 4
 5from sqlglot import alias, exp
 6from sqlglot.errors import OptimizeError
 7from sqlglot.optimizer.scope import traverse_scope
 8from sqlglot.schema import ensure_schema
 9
10if t.TYPE_CHECKING:
11    from sqlglot._typing import E
12    from sqlglot.schema import Schema
13    from sqlglot.dialects.dialect import DialectType
14
15
16def isolate_table_selects(
17    expression: E,
18    schema: t.Optional[t.Dict | Schema] = None,
19    dialect: DialectType = None,
20) -> E:
21    schema = ensure_schema(schema, dialect=dialect)
22
23    for scope in traverse_scope(expression):
24        if len(scope.selected_sources) == 1:
25            continue
26
27        for _, source in scope.selected_sources.values():
28            assert source.parent
29
30            if (
31                not isinstance(source, exp.Table)
32                or not schema.column_names(source)
33                or isinstance(source.parent, exp.Subquery)
34                or isinstance(source.parent.parent, exp.Table)
35            ):
36                continue
37
38            if not source.alias:
39                raise OptimizeError("Tables require an alias. Run qualify_tables optimization.")
40
41            source.replace(
42                exp.select("*")
43                .from_(
44                    alias(source, source.alias_or_name, table=True),
45                    copy=False,
46                )
47                .subquery(source.alias, copy=False)
48            )
49
50    return expression
def isolate_table_selects( expression: ~E, schema: Union[Dict, sqlglot.schema.Schema, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> ~E:
17def isolate_table_selects(
18    expression: E,
19    schema: t.Optional[t.Dict | Schema] = None,
20    dialect: DialectType = None,
21) -> E:
22    schema = ensure_schema(schema, dialect=dialect)
23
24    for scope in traverse_scope(expression):
25        if len(scope.selected_sources) == 1:
26            continue
27
28        for _, source in scope.selected_sources.values():
29            assert source.parent
30
31            if (
32                not isinstance(source, exp.Table)
33                or not schema.column_names(source)
34                or isinstance(source.parent, exp.Subquery)
35                or isinstance(source.parent.parent, exp.Table)
36            ):
37                continue
38
39            if not source.alias:
40                raise OptimizeError("Tables require an alias. Run qualify_tables optimization.")
41
42            source.replace(
43                exp.select("*")
44                .from_(
45                    alias(source, source.alias_or_name, table=True),
46                    copy=False,
47                )
48                .subquery(source.alias, copy=False)
49            )
50
51    return expression