"""
-import itertools, re
+import itertools
+import re
from operator import attrgetter
from .. import util, exc, inspection
# there is some inconsistency here between the usage of
# inspect() vs. checking for Visitable and __clause_element__.
# Ideally all functions here would derive from inspect(),
-# this is a work in progress. In some cases performance is a concern
-# also.
+# however the inspect() versions add significant callcount
+# overhead for critical functions like _interpret_as_column_or_from().
+# Generally, the column-based functions are more performance critical
+# and are fine just checking for __clause_element__(). it's only
+# _interpret_as_from() where we'd like to be able to receive ORM entities
+# that have no defined namespace, hence inspect() is needed there.
def _column_as_key(element):
if isinstance(element, basestring):
return element
def _is_literal(element):
- insp = inspection.inspect(element, raiseerr=False)
-
- return insp is None and not isinstance(element, Visitable)
+ return not isinstance(element, Visitable) and \
+ not hasattr(element, '__clause_element__')
def _only_column_elements_or_none(element, name):
if element is None:
return _only_column_elements(element, name)
def _only_column_elements(element, name):
- insp = inspection.inspect(element, raiseerr=False)
- if insp is None or \
- not hasattr(insp, "expression") or \
- not isinstance(insp.expression, ColumnElement):
+ if hasattr(element, '__clause_element__'):
+ element = element.__clause_element__()
+ if not isinstance(element, ColumnElement):
raise exc.ArgumentError(
"Column-based expression object expected for argument "
"'%s'; got: '%s', type %s" % (name, element, type(element)))
- return insp.expression
+ return element
+
def _literal_as_binds(element, name=None, type_=None):
- insp = inspection.inspect(element, raiseerr=False)
- if insp is None:
+ if hasattr(element, '__clause_element__'):
+ return element.__clause_element__()
+ elif not isinstance(element, Visitable):
if element is None:
- return _const_expr(element)
+ return null()
else:
- return BindParameter(name, element, type_=type_, unique=True)
- elif insp.is_clause_element:
- return insp
+ return _BindParamClause(name, element, type_=type_, unique=True)
else:
- return insp.expression
+ return element
+def _interpret_as_column_or_from(element):
+ if isinstance(element, Visitable):
+ return element
+ elif hasattr(element, '__clause_element__'):
+ return element.__clause_element__()
-def _interpret_as_from(element):
insp = inspection.inspect(element, raiseerr=False)
if insp is None:
if isinstance(element, (util.NoneType, bool)):
return _const_expr(element)
- elif isinstance(element, basestring):
- return TextClause(unicode(element))
elif hasattr(insp, "selectable"):
return insp.selectable
- else:
- raise exc.ArgumentError("FROM expression expected")
-def _literal_as_column(element):
- insp = inspection.inspect(element, raiseerr=False)
- if insp is not None:
- if hasattr(insp, "expression"):
- return insp.expression
- elif hasattr(insp, "selectable"):
- return insp.selectable
- elif insp.is_clause_element:
- return insp
return literal_column(str(element))
+def _interpret_as_from(element):
+ insp = inspection.inspect(element, raiseerr=False)
+ if insp is None:
+ if isinstance(element, basestring):
+ return TextClause(unicode(element))
+ elif hasattr(insp, "selectable"):
+ return insp.selectable
+ raise exc.ArgumentError("FROM expression expected")
def _const_expr(element):
if element is None:
if cols_present:
self._raw_columns = []
for c in columns:
- c = _literal_as_column(c)
+ c = _interpret_as_column_or_from(c)
if isinstance(c, ScalarSelect):
c = c.self_group(against=operators.comma_op)
self._raw_columns.append(c)
self._reset_exported()
rc = []
for c in columns:
- c = _literal_as_column(c)
+ c = _interpret_as_column_or_from(c)
if isinstance(c, ScalarSelect):
c = c.self_group(against=operators.comma_op)
rc.append(c)
"""
self._reset_exported()
- column = _literal_as_column(column)
+ column = _interpret_as_column_or_from(column)
if isinstance(column, ScalarSelect):
column = column.self_group(against=operators.comma_op)