Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
"""
|
|
|
|
Code to manage the creation and SQL rendering of 'where' constraints.
|
|
|
|
"""
|
|
|
|
import datetime
|
|
|
|
|
|
|
|
from django.utils import tree
|
|
|
|
from django.db import connection
|
|
|
|
from django.db.models.fields import Field
|
|
|
|
from django.db.models.query_utils import QueryWrapper
|
|
|
|
from datastructures import EmptyResultSet, FullResultSet
|
|
|
|
|
|
|
|
# Connection types
|
|
|
|
AND = 'AND'
|
|
|
|
OR = 'OR'
|
|
|
|
|
|
|
|
class WhereNode(tree.Node):
|
|
|
|
"""
|
|
|
|
Used to represent the SQL where-clause.
|
|
|
|
|
|
|
|
The class is tied to the Query class that created it (in order to create
|
2008-06-12 11:37:13 +08:00
|
|
|
the correct SQL).
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
|
|
|
|
The children in this tree are usually either Q-like objects or lists of
|
2008-06-27 11:27:20 +08:00
|
|
|
[table_alias, field_name, db_type, lookup_type, value_annotation,
|
|
|
|
params]. However, a child could also be any class with as_sql() and
|
|
|
|
relabel_aliases() methods.
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
"""
|
|
|
|
default = AND
|
|
|
|
|
2008-07-04 14:42:58 +08:00
|
|
|
def add(self, data, connector):
|
|
|
|
"""
|
|
|
|
Add a node to the where-tree. If the data is a list or tuple, it is
|
|
|
|
expected to be of the form (alias, col_name, field_obj, lookup_type,
|
|
|
|
value), which is then slightly munged before being stored (to avoid
|
|
|
|
storing any reference to field objects). Otherwise, the 'data' is
|
|
|
|
stored unchanged and can be anything with an 'as_sql()' method.
|
|
|
|
"""
|
|
|
|
if not isinstance(data, (list, tuple)):
|
|
|
|
super(WhereNode, self).add(data, connector)
|
|
|
|
return
|
|
|
|
|
|
|
|
alias, col, field, lookup_type, value = data
|
|
|
|
if field:
|
|
|
|
params = field.get_db_prep_lookup(lookup_type, value)
|
|
|
|
db_type = field.db_type()
|
|
|
|
else:
|
|
|
|
# This is possible when we add a comparison to NULL sometimes (we
|
|
|
|
# don't really need to waste time looking up the associated field
|
|
|
|
# object).
|
|
|
|
params = Field().get_db_prep_lookup(lookup_type, value)
|
|
|
|
db_type = None
|
|
|
|
if isinstance(value, datetime.datetime):
|
|
|
|
annotation = datetime.datetime
|
|
|
|
else:
|
|
|
|
annotation = bool(value)
|
|
|
|
super(WhereNode, self).add((alias, col, db_type, lookup_type,
|
|
|
|
annotation, params), connector)
|
|
|
|
|
|
|
|
def as_sql(self, qn=None):
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
"""
|
|
|
|
Returns the SQL version of the where clause and the value to be
|
|
|
|
substituted in. Returns None, None if this node is empty.
|
|
|
|
|
|
|
|
If 'node' is provided, that is the root of the SQL generation
|
|
|
|
(generally not needed except by the internal implementation for
|
|
|
|
recursion).
|
|
|
|
"""
|
|
|
|
if not qn:
|
|
|
|
qn = connection.ops.quote_name
|
2008-07-04 14:42:58 +08:00
|
|
|
if not self.children:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
return None, []
|
|
|
|
result = []
|
|
|
|
result_params = []
|
|
|
|
empty = True
|
2008-07-04 14:42:58 +08:00
|
|
|
for child in self.children:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
try:
|
|
|
|
if hasattr(child, 'as_sql'):
|
|
|
|
sql, params = child.as_sql(qn=qn)
|
|
|
|
else:
|
2008-07-04 14:42:58 +08:00
|
|
|
# A leaf node in the tree.
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
sql, params = self.make_atom(child, qn)
|
|
|
|
except EmptyResultSet:
|
2008-07-04 14:42:58 +08:00
|
|
|
if self.connector == AND and not self.negated:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
# We can bail out early in this particular case (only).
|
|
|
|
raise
|
2008-07-04 14:42:58 +08:00
|
|
|
elif self.negated:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
empty = False
|
|
|
|
continue
|
|
|
|
except FullResultSet:
|
|
|
|
if self.connector == OR:
|
2008-07-04 14:42:58 +08:00
|
|
|
if self.negated:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
empty = True
|
|
|
|
break
|
|
|
|
# We match everything. No need for any constraints.
|
|
|
|
return '', []
|
2008-07-04 14:42:58 +08:00
|
|
|
if self.negated:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
empty = True
|
|
|
|
continue
|
|
|
|
empty = False
|
|
|
|
if sql:
|
2008-07-04 14:42:58 +08:00
|
|
|
result.append(sql)
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
result_params.extend(params)
|
|
|
|
if empty:
|
|
|
|
raise EmptyResultSet
|
2008-07-04 14:42:58 +08:00
|
|
|
|
|
|
|
conn = ' %s ' % self.connector
|
|
|
|
sql_string = conn.join(result)
|
|
|
|
if sql_string:
|
|
|
|
if self.negated:
|
|
|
|
sql_string = 'NOT (%s)' % sql_string
|
|
|
|
elif len(self.children) != 1:
|
|
|
|
sql_string = '(%s)' % sql_string
|
|
|
|
return sql_string, result_params
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
|
|
|
|
def make_atom(self, child, qn):
|
|
|
|
"""
|
2008-07-04 14:42:58 +08:00
|
|
|
Turn a tuple (table_alias, column_name, db_type, lookup_type,
|
2008-06-27 11:27:20 +08:00
|
|
|
value_annot, params) into valid SQL.
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
|
|
|
|
Returns the string for the SQL fragment and the parameters to use for
|
|
|
|
it.
|
|
|
|
"""
|
2008-06-27 11:27:20 +08:00
|
|
|
table_alias, name, db_type, lookup_type, value_annot, params = child
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
if table_alias:
|
|
|
|
lhs = '%s.%s' % (qn(table_alias), qn(name))
|
|
|
|
else:
|
|
|
|
lhs = qn(name)
|
|
|
|
field_sql = connection.ops.field_cast_sql(db_type) % lhs
|
|
|
|
|
2008-06-27 11:27:20 +08:00
|
|
|
if value_annot is datetime.datetime:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
cast_sql = connection.ops.datetime_cast_sql()
|
|
|
|
else:
|
|
|
|
cast_sql = '%s'
|
|
|
|
|
|
|
|
if isinstance(params, QueryWrapper):
|
|
|
|
extra, params = params.data
|
|
|
|
else:
|
|
|
|
extra = ''
|
|
|
|
|
|
|
|
if lookup_type in connection.operators:
|
|
|
|
format = "%s %%s %s" % (connection.ops.lookup_cast(lookup_type),
|
|
|
|
extra)
|
|
|
|
return (format % (field_sql,
|
|
|
|
connection.operators[lookup_type] % cast_sql), params)
|
|
|
|
|
|
|
|
if lookup_type == 'in':
|
2008-06-27 11:27:20 +08:00
|
|
|
if not value_annot:
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
raise EmptyResultSet
|
|
|
|
if extra:
|
|
|
|
return ('%s IN %s' % (field_sql, extra), params)
|
2008-06-27 11:27:20 +08:00
|
|
|
return ('%s IN (%s)' % (field_sql, ', '.join(['%s'] * len(params))),
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
params)
|
|
|
|
elif lookup_type in ('range', 'year'):
|
|
|
|
return ('%s BETWEEN %%s and %%s' % field_sql, params)
|
|
|
|
elif lookup_type in ('month', 'day'):
|
|
|
|
return ('%s = %%s' % connection.ops.date_extract_sql(lookup_type,
|
|
|
|
field_sql), params)
|
|
|
|
elif lookup_type == 'isnull':
|
2008-06-27 11:27:20 +08:00
|
|
|
return ('%s IS %sNULL' % (field_sql,
|
|
|
|
(not value_annot and 'NOT ' or '')), ())
|
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
|
|
|
elif lookup_type == 'search':
|
|
|
|
return (connection.ops.fulltext_search_sql(field_sql), params)
|
|
|
|
elif lookup_type in ('regex', 'iregex'):
|
|
|
|
return connection.ops.regex_lookup(lookup_type) % (field_sql, cast_sql), params
|
|
|
|
|
|
|
|
raise TypeError('Invalid lookup_type: %r' % lookup_type)
|
|
|
|
|
|
|
|
def relabel_aliases(self, change_map, node=None):
|
|
|
|
"""
|
|
|
|
Relabels the alias values of any children. 'change_map' is a dictionary
|
|
|
|
mapping old (current) alias values to the new values.
|
|
|
|
"""
|
|
|
|
if not node:
|
|
|
|
node = self
|
|
|
|
for pos, child in enumerate(node.children):
|
|
|
|
if hasattr(child, 'relabel_aliases'):
|
|
|
|
child.relabel_aliases(change_map)
|
|
|
|
elif isinstance(child, tree.Node):
|
|
|
|
self.relabel_aliases(change_map, child)
|
|
|
|
else:
|
|
|
|
if child[0] in change_map:
|
|
|
|
node.children[pos] = (change_map[child[0]],) + child[1:]
|
|
|
|
|
|
|
|
class EverythingNode(object):
|
|
|
|
"""
|
|
|
|
A node that matches everything.
|
|
|
|
"""
|
|
|
|
def as_sql(self, qn=None):
|
|
|
|
raise FullResultSet
|
|
|
|
|
|
|
|
def relabel_aliases(self, change_map, node=None):
|
|
|
|
return
|