Skip to content

Commit 38ec768

Browse files
committed
Reduce number of AST walks in while_changing
1 parent b536e81 commit 38ec768

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

sqlglot/helper.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,25 +211,31 @@ def while_changing(expression: Expression, func: t.Callable[[Expression], E]) ->
211211
Returns:
212212
The transformed expression.
213213
"""
214+
end_hash: t.Optional[int] = None
215+
214216
while True:
215-
for n in reversed(tuple(expression.walk())):
216-
n._hash = hash(n)
217+
# No need to walk the AST– we've already cached the hashes in the previous iteration
218+
if end_hash is None:
219+
for n in reversed(tuple(expression.walk())):
220+
n._hash = hash(n)
217221

218222
start_hash = hash(expression)
219223
expression = func(expression)
220224

225+
expression_nodes = tuple(expression.walk())
226+
221227
# Uncache previous caches so we can recompute them
222-
for n in reversed(tuple(expression.walk())):
228+
for n in reversed(expression_nodes):
223229
n._hash = None
224230
n._hash = hash(n)
225231

226232
end_hash = hash(expression)
227233

228-
# ... and reset the hash so we don't risk it becoming out of date if a mutation happens
229-
for n in expression.walk():
230-
n._hash = None
231-
232234
if start_hash == end_hash:
235+
# ... and reset the hash so we don't risk it becoming out of date if a mutation happens
236+
for n in expression_nodes:
237+
n._hash = None
238+
233239
break
234240

235241
return expression

0 commit comments

Comments
 (0)