summaryrefslogtreecommitdiff
path: root/test/sql/test_compare.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-12-16 17:06:43 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-07-03 23:39:51 -0400
commit3dc9a4a2392d033f9d1bd79dd6b6ecea6281a61c (patch)
tree1041bccb37422f526dccb5b1e57ffad1c702549b /test/sql/test_compare.py
parent5060043e8e95ab0aab5f63ed288c1426c46da66e (diff)
downloadsqlalchemy-3dc9a4a2392d033f9d1bd79dd6b6ecea6281a61c.tar.gz
introduce deferred lambdas
The coercions system allows us to add in lambdas as arguments to Core and ORM elements without changing them at all. By allowing the lambda to produce a deterministic cache key where we can also cheat and yank out literal parameters means we can move towards having 90% of "baked" functionality in a clearer way right in Core / ORM. As a second step, we can have whole statements inside the lambda, and can then add generation with __add__(), so then we have 100% of "baked" functionality with full support of ad-hoc literal values. Adds some more short_selects tests for the moment for comparison. Other tweaks inside cache key generation as we're trying to approach a certain level of performance such that we can remove the use of "baked" from the loader strategies. As we have not yet closed #4639, however the caching feature has been fully integrated as of b0cfa7379cf8513a821a3dbe3028c4965d9f85bd, we will also add complete caching documentation here and close that issue as well. Closes: #4639 Fixes: #5380 Change-Id: If91f61527236fd4d7ae3cad1f24c38be921c90ba
Diffstat (limited to 'test/sql/test_compare.py')
-rw-r--r--test/sql/test_compare.py68
1 files changed, 67 insertions, 1 deletions
diff --git a/test/sql/test_compare.py b/test/sql/test_compare.py
index 694410134..da588b988 100644
--- a/test/sql/test_compare.py
+++ b/test/sql/test_compare.py
@@ -37,6 +37,7 @@ from sqlalchemy.sql import dml
from sqlalchemy.sql import False_
from sqlalchemy.sql import func
from sqlalchemy.sql import operators
+from sqlalchemy.sql import roles
from sqlalchemy.sql import True_
from sqlalchemy.sql import type_coerce
from sqlalchemy.sql import visitors
@@ -55,6 +56,8 @@ from sqlalchemy.sql.elements import UnaryExpression
from sqlalchemy.sql.functions import FunctionElement
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.sql.functions import ReturnTypeFromArgs
+from sqlalchemy.sql.lambdas import lambda_stmt
+from sqlalchemy.sql.lambdas import LambdaElement
from sqlalchemy.sql.selectable import _OffsetLimitParam
from sqlalchemy.sql.selectable import AliasedReturnsRows
from sqlalchemy.sql.selectable import FromGrouping
@@ -791,6 +794,69 @@ class CoreFixtures(object):
if util.py37:
fixtures.append(_update_dml_w_dicts)
+ def _lambda_fixtures():
+ def one():
+ return LambdaElement(
+ lambda: table_a.c.a == column("q"), roles.WhereHavingRole
+ )
+
+ def two():
+ r = random.randint(1, 10)
+ q = 20
+ return LambdaElement(
+ lambda: table_a.c.a + q == r, roles.WhereHavingRole
+ )
+
+ some_value = random.randint(20, 30)
+
+ def three(y):
+ return LambdaElement(
+ lambda: and_(table_a.c.a == some_value, table_a.c.b > y),
+ roles.WhereHavingRole,
+ )
+
+ class Foo:
+ x = 10
+ y = 15
+
+ def four():
+ return LambdaElement(
+ lambda: and_(table_a.c.a == Foo.x), roles.WhereHavingRole
+ )
+
+ def five():
+ return LambdaElement(
+ lambda: and_(table_a.c.a == Foo.x, table_a.c.b == Foo.y),
+ roles.WhereHavingRole,
+ )
+
+ def six():
+ d = {"g": random.randint(40, 45)}
+
+ return LambdaElement(
+ lambda: and_(table_a.c.b == d["g"]), roles.WhereHavingRole
+ )
+
+ def seven():
+ # lambda statements don't collect bindparameter objects
+ # for fixed values, has to be in a variable
+ value = random.randint(10, 20)
+ return lambda_stmt(lambda: future_select(table_a)) + (
+ lambda s: s.where(table_a.c.a == value)
+ )
+
+ return [
+ one(),
+ two(),
+ three(random.randint(5, 10)),
+ four(),
+ five(),
+ six(),
+ seven(),
+ ]
+
+ dont_compare_values_fixtures.append(_lambda_fixtures)
+
class CacheKeyFixture(object):
def _run_cache_key_fixture(self, fixture, compare_values):
@@ -1076,7 +1142,7 @@ class CompareAndCopyTest(CoreFixtures, fixtures.TestBase):
need = set(
cls
for cls in class_hierarchy(ClauseElement)
- if issubclass(cls, (ColumnElement, Selectable))
+ if issubclass(cls, (ColumnElement, Selectable, LambdaElement))
and (
"__init__" in cls.__dict__
or issubclass(cls, AliasedReturnsRows)