summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-10-23 02:22:57 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-10-23 02:22:57 +0000
commit1ccdfb517237408f746068f466548f9331468d7f (patch)
treea3bd6b8c311a6a7f9aca539e288337a7cd32ef3a /lib/sqlalchemy/sql
parent3d0fe5bfe2e15e553279a8420ed048e6b84cc72a (diff)
downloadsqlalchemy-1ccdfb517237408f746068f466548f9331468d7f.tar.gz
call count pinata party
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py34
-rw-r--r--lib/sqlalchemy/sql/expression.py43
2 files changed, 53 insertions, 24 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 51664d64e..ac46d5768 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -109,6 +109,22 @@ FUNCTIONS = {
functions.user: 'USER'
}
+
+class _CompileLabel(object):
+ """lightweight label object which acts as an expression._Label."""
+
+ __metaclass__ = sql._FigureVisitName
+ __visit_name__ = 'label'
+ __slots__ = 'element', 'name'
+
+ def __init__(self, col, name):
+ self.element = col
+ self.name = name
+
+ @property
+ def quote(self):
+ return self.element.quote
+
class DefaultCompiler(engine.Compiled):
"""Default implementation of Compiled.
@@ -175,9 +191,7 @@ class DefaultCompiler(engine.Compiled):
self.string = self.process(self.statement)
def process(self, obj, **kwargs):
- meth = getattr(self, "visit_%s" % obj.__visit_name__, None)
- if meth:
- return meth(obj, **kwargs)
+ return obj._compiler_dispatch(self, **kwargs)
def is_subquery(self):
return self.stack and len(self.stack) > 1 and self.stack[-1].get('from')
@@ -243,8 +257,8 @@ class DefaultCompiler(engine.Compiled):
if result_map is not None:
result_map[name.lower()] = (name, (column, ), column.type)
-
- if getattr(column, "is_literal", False):
+
+ if column.is_literal:
name = self.escape_literal_column(name)
else:
name = self.preparer.quote(name, column.quote)
@@ -252,7 +266,7 @@ class DefaultCompiler(engine.Compiled):
if column.table is None or not column.table.named_with_column:
return name
else:
- if getattr(column.table, 'schema', None):
+ if column.table.schema:
schema_prefix = self.preparer.quote(column.table.schema, column.table.quote_schema) + '.'
else:
schema_prefix = ''
@@ -432,8 +446,8 @@ class DefaultCompiler(engine.Compiled):
if isinstance(column, sql._Label):
return column
- if select.use_labels and getattr(column, '_label', None):
- return column.label(column._label)
+ if select.use_labels and column._label:
+ return _CompileLabel(column, column._label)
if \
asfrom and \
@@ -441,9 +455,9 @@ class DefaultCompiler(engine.Compiled):
not column.is_literal and \
column.table is not None and \
not isinstance(column.table, sql.Select):
- return column.label(column.name)
+ return _CompileLabel(column, column.name)
elif not isinstance(column, (sql._UnaryExpression, sql._TextClause, sql._BindParamClause)) and (not hasattr(column, 'name') or isinstance(column, sql._Function)):
- return column.label(column.anon_label)
+ return _CompileLabel(column, column.anon_label)
else:
return column
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index cb2bcd6d6..39c31c8cb 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -944,7 +944,6 @@ def is_column(col):
"""True if ``col`` is an instance of ``ColumnElement``."""
return isinstance(col, ColumnElement)
-
class _FigureVisitName(type):
def __init__(cls, clsname, bases, dict):
if not '__visit_name__' in cls.__dict__:
@@ -952,6 +951,21 @@ class _FigureVisitName(type):
x = m.group(1)
x = re.sub(r'(?!^)[A-Z]', lambda m:'_'+m.group(0).lower(), x)
cls.__visit_name__ = x.lower()
+
+ # set up an optimized visit dispatch function
+ # for use by the compiler
+ visit_name = cls.__dict__["__visit_name__"]
+ if isinstance(visit_name, str):
+ func_text = "def _compiler_dispatch(self, visitor, **kw):\n"\
+ " return visitor.visit_%s(self, **kw)" % visit_name
+ else:
+ func_text = "def _compiler_dispatch(self, visitor, **kw):\n"\
+ " return getattr(visitor, 'visit_%s' % self.__visit_name__)(self, **kw)"
+
+ env = locals().copy()
+ exec func_text in env
+ cls._compiler_dispatch = env['_compiler_dispatch']
+
super(_FigureVisitName, cls).__init__(clsname, bases, dict)
class ClauseElement(object):
@@ -1682,6 +1696,7 @@ class FromClause(Selectable):
named_with_column = False
_hide_froms = []
quote = None
+ schema = None
def _get_from_objects(self, **modifiers):
return []
@@ -2553,19 +2568,19 @@ class _Label(ColumnElement):
def __init__(self, name, element, type_=None):
while isinstance(element, _Label):
element = element.element
- self.name = name or "{ANON %d %s}" % (id(self), getattr(element, 'name', 'anon'))
- self.element = element.self_group(against=operators.as_)
- self.type = sqltypes.to_instance(type_ or getattr(element, 'type', None))
+ self.name = self.key = self._label = name or "{ANON %d %s}" % (id(self), getattr(element, 'name', 'anon'))
+ self._element = element
+ self._type = type_
self.quote = element.quote
-
- @property
- def key(self):
- return self.name
-
- @property
- def _label(self):
- return self.name
-
+
+ @util.memoized_property
+ def type(self):
+ return sqltypes.to_instance(self._type or getattr(element, 'type', None))
+
+ @util.memoized_property
+ def element(self):
+ return self._element.self_group(against=operators.as_)
+
def _proxy_attr(name):
get = attrgetter(name)
def attr(self):
@@ -2693,7 +2708,7 @@ class TableClause(_Immutable, FromClause):
"""
named_with_column = True
-
+
def __init__(self, name, *columns):
super(TableClause, self).__init__()
self.name = self.fullname = name