@@ -61,74 +61,79 @@ def simplify(
61
61
62
62
dialect = Dialect .get_or_raise (dialect )
63
63
64
- def _simplify (expression , root = True ):
65
- if (
66
- max_depth
67
- and isinstance (expression , exp .Connector )
68
- and not isinstance (expression .parent , exp .Connector )
69
- ):
70
- depth = connector_depth (expression )
71
- if depth > max_depth :
72
- logger .info (
73
- f"Skipping simplification because connector depth { depth } exceeds max { max_depth } "
74
- )
75
- return expression
64
+ def _simplify (expression ):
65
+ stack = []
76
66
77
- if expression .meta .get (FINAL ):
78
- return expression
67
+ for node in expression .dfs (prune = lambda n : n .meta .get (FINAL )):
68
+ if node .meta .get (FINAL ):
69
+ continue
70
+
71
+ # group by expressions cannot be simplified, for example
72
+ # select x + 1 + 1 FROM y GROUP BY x + 1 + 1
73
+ # the projection must exactly match the group by key
74
+ group = node .args .get ("group" )
75
+
76
+ if group and hasattr (node , "selects" ):
77
+ groups = set (group .expressions )
78
+ group .meta [FINAL ] = True
79
+
80
+ for s in node .selects :
81
+ for n in s .walk ():
82
+ if n in groups :
83
+ s .meta [FINAL ] = True
84
+ break
85
+
86
+ having = node .args .get ("having" )
87
+ if having :
88
+ for n in having .walk ():
89
+ if n in groups :
90
+ having .meta [FINAL ] = True
91
+ break
92
+
93
+ parent = node .parent
94
+ root = node is expression
95
+
96
+ new_node = rewrite_between (node )
97
+ new_node = uniq_sort (new_node , root )
98
+ new_node = absorb_and_eliminate (new_node , root )
99
+ new_node = simplify_concat (new_node )
100
+ new_node = simplify_conditionals (new_node )
101
+
102
+ if constant_propagation :
103
+ new_node = propagate_constants (new_node , root )
104
+
105
+ if new_node is not node :
106
+ node .replace (new_node )
107
+
108
+ stack .append ((new_node , parent ))
109
+
110
+ while stack :
111
+ node , parent = stack .pop ()
112
+ root = node is expression
113
+
114
+ # Resets parent, arg_key, index pointers
115
+ exp .replace_children (node , lambda n : n )
116
+
117
+ # Post-order transformations
118
+ new_node = simplify_not (node )
119
+ new_node = flatten (new_node )
120
+ new_node = simplify_connectors (new_node , root )
121
+ new_node = remove_complements (new_node , root )
122
+ new_node = simplify_coalesce (new_node , dialect )
123
+
124
+ new_node .parent = parent
125
+
126
+ new_node = simplify_literals (new_node , root )
127
+ new_node = simplify_equality (new_node )
128
+ new_node = simplify_parens (new_node )
129
+ new_node = simplify_datetrunc (new_node , dialect )
130
+ new_node = sort_comparison (new_node )
131
+ new_node = simplify_startswith (new_node )
132
+
133
+ if new_node is not node :
134
+ node .replace (new_node )
79
135
80
- # group by expressions cannot be simplified, for example
81
- # select x + 1 + 1 FROM y GROUP BY x + 1 + 1
82
- # the projection must exactly match the group by key
83
- group = expression .args .get ("group" )
84
-
85
- if group and hasattr (expression , "selects" ):
86
- groups = set (group .expressions )
87
- group .meta [FINAL ] = True
88
-
89
- for e in expression .selects :
90
- for node in e .walk ():
91
- if node in groups :
92
- e .meta [FINAL ] = True
93
- break
94
-
95
- having = expression .args .get ("having" )
96
- if having :
97
- for node in having .walk ():
98
- if node in groups :
99
- having .meta [FINAL ] = True
100
- break
101
-
102
- # Pre-order transformations
103
- node = expression
104
- node = rewrite_between (node )
105
- node = uniq_sort (node , root )
106
- node = absorb_and_eliminate (node , root )
107
- node = simplify_concat (node )
108
- node = simplify_conditionals (node )
109
-
110
- if constant_propagation :
111
- node = propagate_constants (node , root )
112
-
113
- exp .replace_children (node , lambda e : _simplify (e , False ))
114
-
115
- # Post-order transformations
116
- node = simplify_not (node )
117
- node = flatten (node )
118
- node = simplify_connectors (node , root )
119
- node = remove_complements (node , root )
120
- node = simplify_coalesce (node , dialect )
121
- node .parent = expression .parent
122
- node = simplify_literals (node , root )
123
- node = simplify_equality (node )
124
- node = simplify_parens (node )
125
- node = simplify_datetrunc (node , dialect )
126
- node = sort_comparison (node )
127
- node = simplify_startswith (node )
128
-
129
- if root :
130
- expression .replace (node )
131
- return node
136
+ return new_node
132
137
133
138
expression = while_changing (expression , _simplify )
134
139
remove_where_true (expression )
0 commit comments