From: Mike Bayer Date: Tue, 17 Oct 2006 11:39:53 +0000 (+0000) Subject: lazy clause generation can handle comparisons of column-containing expressions such... X-Git-Tag: rel_0_3_0~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5c3ec3620c3499c3a8df5b7ad8abc860699f598;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git lazy clause generation can handle comparisons of column-containing expressions such as functions, within a limited scope --- diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 4b04bffdcd..6bbeb65f1c 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -240,21 +240,35 @@ class LazyLoader(AbstractRelationLoader): def column_in_table(table, column): return table.corresponding_column(column, raiseerr=False, keys_ok=False) is not None + def find_column_in_expr(expr): + if not isinstance(expr, sql.ColumnElement): + return None + columns = [] + class FindColumnInColumnClause(sql.ClauseVisitor): + def visit_column(self, c): + columns.append(c) + expr.accept_visitor(FindColumnInColumnClause()) + return len(columns) and columns[0] or None + def bind_label(): return "lazy_" + hex(random.randint(0, 65535))[2:] def visit_binary(binary): - circular = isinstance(binary.left, schema.Column) and isinstance(binary.right, schema.Column) and binary.left.table is binary.right.table - if isinstance(binary.left, schema.Column) and isinstance(binary.right, schema.Column) and ((not circular and column_in_table(table, binary.left)) or (circular and binary.right in foreignkey)): - col = binary.left - binary.left = binds.setdefault(binary.left, - sql.bindparam(bind_label(), None, shortname=binary.left.name, type=binary.right.type)) - reverse[binary.right] = binds[col] - - if isinstance(binary.right, schema.Column) and isinstance(binary.left, schema.Column) and ((not circular and column_in_table(table, binary.right)) or (circular and binary.left in foreignkey)): - col = binary.right - binary.right = binds.setdefault(binary.right, - sql.bindparam(bind_label(), None, shortname=binary.right.name, type=binary.left.type)) - reverse[binary.left] = binds[col] + leftcol = find_column_in_expr(binary.left) + rightcol = find_column_in_expr(binary.right) + if leftcol is None or rightcol is None: + return + circular = leftcol.table is rightcol.table + if ((not circular and column_in_table(table, leftcol)) or (circular and rightcol in foreignkey)): + col = leftcol + binary.left = binds.setdefault(leftcol, + sql.bindparam(bind_label(), None, shortname=leftcol.name, type=binary.right.type)) + reverse[rightcol] = binds[col] + + if (leftcol is not rightcol) and ((not circular and column_in_table(table, rightcol)) or (circular and leftcol in foreignkey)): + col = rightcol + binary.right = binds.setdefault(rightcol, + sql.bindparam(bind_label(), None, shortname=rightcol.name, type=binary.left.type)) + reverse[leftcol] = binds[col] lazywhere = primaryjoin.copy_container() li = mapperutil.BinaryVisitor(visit_binary)