summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/visitors.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-11-08 18:06:21 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-11-08 18:06:21 +0000
commit2cbb133567befca7e92f8e3bbc0aaae96b1781a8 (patch)
treec5848def75457a3bb1c5887af09ee5bd7fee1b83 /lib/sqlalchemy/sql/visitors.py
parent7a25be0f4214720198029e85c2f1d18f4fc8bad3 (diff)
downloadsqlalchemy-2cbb133567befca7e92f8e3bbc0aaae96b1781a8.tar.gz
more changes to traverse-and-clone; a particular element will only be cloned once and is
then re-used. the FROM calculation of a Select normalizes the list of hide_froms against all previous incarnations of each FROM clause, using a tag attached from cloned clause to previous.
Diffstat (limited to 'lib/sqlalchemy/sql/visitors.py')
-rw-r--r--lib/sqlalchemy/sql/visitors.py15
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py
index 9bc5d2479..1a0629a17 100644
--- a/lib/sqlalchemy/sql/visitors.py
+++ b/lib/sqlalchemy/sql/visitors.py
@@ -47,10 +47,19 @@ class ClauseVisitor(object):
traversal.insert(0, t)
for c in t.get_children(**self.__traverse_options__):
stack.append(c)
-
+
def traverse(self, obj, stop_on=None, clone=False):
+
if clone:
- obj = obj._clone()
+ cloned = {}
+ def do_clone(obj):
+ # the full traversal will only make a clone of a particular element
+ # once.
+ if obj not in cloned:
+ cloned[obj] = obj._clone()
+ return cloned[obj]
+
+ obj = do_clone(obj)
stack = [obj]
traversal = []
@@ -59,7 +68,7 @@ class ClauseVisitor(object):
if stop_on is None or t not in stop_on:
traversal.insert(0, t)
if clone:
- t._copy_internals()
+ t._copy_internals(clone=do_clone)
for c in t.get_children(**self.__traverse_options__):
stack.append(c)
for target in traversal: