diff options
Diffstat (limited to 'sqlglot/optimizer/merge_subqueries.py')
-rw-r--r-- | sqlglot/optimizer/merge_subqueries.py | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/sqlglot/optimizer/merge_subqueries.py b/sqlglot/optimizer/merge_subqueries.py index 16aaf17..70172f4 100644 --- a/sqlglot/optimizer/merge_subqueries.py +++ b/sqlglot/optimizer/merge_subqueries.py @@ -314,13 +314,27 @@ def _merge_where(outer_scope, inner_scope, from_or_join): if not where or not where.this: return + expression = outer_scope.expression + if isinstance(from_or_join, exp.Join): # Merge predicates from an outer join to the ON clause - from_or_join.on(where.this, copy=False) - from_or_join.set("on", simplify(from_or_join.args.get("on"))) - else: - outer_scope.expression.where(where.this, copy=False) - outer_scope.expression.set("where", simplify(outer_scope.expression.args.get("where"))) + # if it only has columns that are already joined + from_ = expression.args.get("from") + sources = {table.alias_or_name for table in from_.expressions} if from_ else {} + + for join in expression.args["joins"]: + source = join.alias_or_name + sources.add(source) + if source == from_or_join.alias_or_name: + break + + if set(exp.column_table_names(where.this)) <= sources: + from_or_join.on(where.this, copy=False) + from_or_join.set("on", simplify(from_or_join.args.get("on"))) + return + + expression.where(where.this, copy=False) + expression.set("where", simplify(expression.args.get("where"))) def _merge_order(outer_scope, inner_scope): |